import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Euler712 {
    static final long kMod = 1000000007L;

    static class PrimeCounter {
        static final int kSieveLimit = 5000000;
        List<Integer> primes = new ArrayList<>();
        int[] pi = new int[kSieveLimit + 1];
        Map<Long, Long> lehmerCache = new HashMap<>();

        PrimeCounter() {
            sieve();
        }

        void sieve() {
            byte[] isPrime = new byte[kSieveLimit + 1];
            java.util.Arrays.fill(isPrime, (byte) 1);
            isPrime[0] = isPrime[1] = 0;

            for (int i = 2; (long) i * i <= kSieveLimit; ++i) {
                if (isPrime[i] != 0) {
                    for (int j = i * i; j <= kSieveLimit; j += i) {
                        isPrime[j] = 0;
                    }
                }
            }

            int count = 0;
            for (int i = 2; i <= kSieveLimit; ++i) {
                if (isPrime[i] != 0) {
                    primes.add(i);
                    count++;
                }
                pi[i] = count;
            }
        }

        long isqrt(long x) {
            long r = (long) Math.sqrt(x);
            while ((r + 1) <= x / (r + 1))
                ++r;
            while (r > 0 && r > x / r)
                --r;
            return r;
        }

        long icbrt(long x) {
            long r = (long) Math.cbrt(x);
            while ((r + 1) <= x / (r + 1) / (r + 1))
                ++r;
            while (r > 0 && r > x / r / r)
                --r;
            return r;
        }

        long iroot4(long x) {
            long r = (long) Math.sqrt(Math.sqrt(x));
            while ((r + 1) <= x / (r + 1) / (r + 1) / (r + 1))
                ++r;
            while (r > 0 && r > x / r / r / r)
                --r;
            return r;
        }

        long phi(long x, int s) {
            if (s == 0)
                return x;
            if (s == 1)
                return x - x / 2;
            if (s == 2)
                return x - x / 2 - x / 3 + x / 6;
            if (s == 3)
                return x - x / 2 - x / 3 - x / 5 + x / 6 + x / 10 + x / 15 - x / 30;

            if (x <= kSieveLimit && (long) primes.get(s - 1) * primes.get(s - 1) > x) {
                return pi[(int) x] - s + 1;
            }
            return phi(x, s - 1) - phi(x / primes.get(s - 1), s - 1);
        }

        long lehmer(long x) {
            if (x <= kSieveLimit) {
                return pi[(int) x];
            }
            if (lehmerCache.containsKey(x)) {
                return lehmerCache.get(x);
            }

            long a = lehmer(iroot4(x));
            long b = lehmer(isqrt(x));
            long c = lehmer(icbrt(x));

            long sum = phi(x, (int) a);
            sum += (b + a - 2) * (b - a + 1) / 2;

            for (long i = a + 1; i <= b; ++i) {
                long p = primes.get((int) (i - 1));
                long w = x / p;
                sum -= lehmer(w);
                if (i <= c) {
                    long bi = lehmer(isqrt(w));
                    for (long j = i; j <= bi; ++j) {
                        long pj = primes.get((int) (j - 1));
                        sum -= lehmer(w / pj) - (j - 1);
                    }
                }
            }

            lehmerCache.put(x, sum);
            return sum;
        }
    }

    public static String solve() {
        long n = 1000000000000L;
        PrimeCounter primeCounter = new PrimeCounter();

        long y = Math.min(n, 100000000L);
        long nMod = n % kMod;
        long[] ans = { 0 };

        java.util.function.BiConsumer<Long, Long> addQ = (q, count) -> {
            long qMod = q % kMod;
            long term = (nMod * qMod % kMod - qMod * qMod % kMod + kMod) % kMod;
            long countMod = count % kMod;
            ans[0] = (ans[0] + 2 * term % kMod * countMod) % kMod;
        };

        long segmentSize = 1000000L;
        int root = (int) Math.sqrt(y);

        byte[] baseMark = new byte[root + 1];
        java.util.Arrays.fill(baseMark, (byte) 1);
        List<Integer> basePrimes = new ArrayList<>();

        for (int i = 2; i <= root; ++i) {
            if (baseMark[i] != 0) {
                basePrimes.add(i);
                if ((long) i * i <= root) {
                    for (int j = i * i; j <= root; j += i) {
                        baseMark[j] = 0;
                    }
                }
            }
        }

        for (long low = 2; low <= y; low += segmentSize) {
            long high = Math.min(y, low + segmentSize - 1);
            byte[] isPrime = new byte[(int) (high - low + 1)];
            java.util.Arrays.fill(isPrime, (byte) 1);

            for (int p : basePrimes) {
                long prime = p;
                long start = (low + prime - 1) / prime * prime;
                long p2 = prime * prime;
                if (start < p2)
                    start = p2;
                if (start > high)
                    continue;

                for (long v = start; v <= high; v += prime) {
                    isPrime[(int) (v - low)] = 0;
                }
            }

            for (long p = low; p <= high; ++p) {
                if (isPrime[(int) (p - low)] != 0) {
                    long power = p;
                    while (power <= n) {
                        addQ.accept(n / power, 1L);
                        if (power > n / p)
                            break;
                        power *= p;
                    }
                }
            }
        }

        if (y < n) {
            long qMax = n / (y + 1);
            for (long q = 1; q <= qMax; ++q) {
                long l = n / (q + 1) + 1;
                long r = n / q;
                if (r <= y)
                    continue;
                if (l <= y)
                    l = y + 1;
                if (l > r)
                    continue;

                long count = primeCounter.lehmer(r) - primeCounter.lehmer(l - 1);
                if (count != 0) {
                    addQ.accept(q, count);
                }
            }
        }

        return Long.toString(ans[0]);
    }

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