import java.math.BigInteger;

public class Euler771 {

    static final long MOD = 1000000007L;

    static long countIntervals(int terms) {
        if (terms < 5)
            return 0;
        long a = terms - 4;
        long b = terms - 3;
        if (a % 2 == 0)
            a /= 2;
        else
            b /= 2;
        a %= MOD;
        b %= MOD;
        return (a * b) % MOD;
    }

    static long countConsecutive(long n) {
        if (n < 5)
            return 0;
        long a = n - 4;
        long b = n - 3;
        if (a % 2 == 0)
            a /= 2;
        else
            b /= 2;
        a %= MOD;
        b %= MOD;
        return (a * b) % MOD;
    }

    static long countHybrid(long n) {
        if (n < 54)
            return 0;
        int terms = 1;
        long v = 2;
        while (v <= n) {
            terms++;
            // avoid overflow, though 10^18 limit means v * 3 won't exceed long max.
            v *= 3;
        }
        if (terms < 5)
            return 0;
        return (terms - 4) % MOD;
    }

    static long countSporadic(long n) {
        long[] lastTerms = { 6, 9, 9, 16, 12, 20, 48, 60, 9, 16 };
        long total = 0;
        for (long v : lastTerms) {
            if (v <= n)
                total++;
        }
        return total % MOD;
    }

    static int floorRoot4(long n) {
        double approx = Math.pow((double) n, 0.25);
        long x = (long) Math.floor(approx);
        while (Math.pow(x + 1, 4) <= n)
            x++;
        while (Math.pow(x, 4) > n && x > 0)
            x--;
        return (int) x;
    }

    static int[] sievePhi(int n) {
        int[] phi = new int[n + 1];
        for (int i = 0; i <= n; i++)
            phi[i] = i;
        for (int i = 2; i <= n; i++) {
            if (phi[i] == i) {
                for (int j = i; j <= n; j += i) {
                    phi[j] -= phi[j] / i;
                }
            }
        }
        return phi;
    }

    static long countGeometric(long n, int root4) {
        if (root4 < 2)
            return 0;
        int[] phi = sievePhi(root4);
        long total = 0;
        for (int p = 2; p <= root4; p++) {
            long pk = (long) p * p * p * p;
            while (pk <= n) {
                long div = n / pk;
                long term = (phi[p] * div) % MOD;
                total = (total + term) % MOD;
                if (n / pk >= (long) p) {
                    pk *= p;
                } else {
                    break;
                }
            }
        }
        return total;
    }

    static int countTerms(long n, long a0, long a1, long m, boolean plus) {
        int terms = 2;
        BigInteger bn = BigInteger.valueOf(n);
        BigInteger bm = BigInteger.valueOf(m);
        BigInteger b0 = BigInteger.valueOf(a0);
        BigInteger b1 = BigInteger.valueOf(a1);
        while (true) {
            BigInteger b2;
            if (plus) {
                b2 = bm.multiply(b1).add(b0);
            } else {
                b2 = bm.multiply(b1).subtract(b0);
            }
            if (b2.compareTo(b1) <= 0 || b2.compareTo(bn) > 0)
                break;
            terms++;
            b0 = b1;
            b1 = b2;
        }
        return terms;
    }

    public static String solve() {
        long n = 1000000000000000000L;
        if (n < 5)
            return "0";

        int root4 = floorRoot4(n);
        long ans = 0;

        ans = (ans + countConsecutive(n)) % MOD;
        ans = (ans + countGeometric(n, root4)) % MOD;

        for (long m = 3; m <= root4; m++) {
            int terms = countTerms(n, 1, m, m, false);
            ans = (ans + countIntervals(terms)) % MOD;
        }

        ans = (ans + countIntervals(countTerms(n, 1, 2, 3, false))) % MOD;
        ans = (ans + countIntervals(countTerms(n, 1, 3, 4, false))) % MOD;

        ans = (ans + countIntervals(countTerms(n, 1, 2, 1, true))) % MOD;
        for (long m = 2; m <= root4; m++) {
            int terms = countTerms(n, 1, m, m, true);
            ans = (ans + countIntervals(terms)) % MOD;
        }

        ans = (ans + countIntervals(countTerms(n, 1, 3, 2, true))) % MOD;

        ans = (ans + countHybrid(n)) % MOD;
        ans = (ans + countSporadic(n)) % MOD;

        return Long.toString(ans);
    }

    public static void main(String[] args) {
        System.out.println(solve());
    }
}
