import java.util.ArrayList;
import java.util.List;

public class Euler517 {

    static final long kMod = 1000000007L;

    static long modPow(long base, long exp, long mod) {
        long result = 1 % mod;
        long cur = base % mod;
        long e = exp;
        while (e > 0) {
            if ((e & 1) == 1) {
                result = (result * cur) % mod;
            }
            cur = (cur * cur) % mod;
            e >>= 1;
        }
        return result;
    }

    static List<Integer> smallPrimesUpTo(int n) {
        boolean[] isPrime = new boolean[n + 1];
        for (int i = 2; i <= n; i++)
            isPrime[i] = true;
        for (int p = 2; p * p <= n; p++) {
            if (isPrime[p]) {
                for (int m = p * p; m <= n; m += p) {
                    isPrime[m] = false;
                }
            }
        }
        List<Integer> out = new ArrayList<>();
        for (int i = 2; i <= n; i++) {
            if (isPrime[i])
                out.add(i);
        }
        return out;
    }

    static List<Integer> segmentedPrimes(int low, int highExclusive) {
        if (highExclusive <= low)
            return new ArrayList<>();
        int root = (int) Math.sqrt(highExclusive - 1) + 1;
        List<Integer> basePrimes = smallPrimesUpTo(root);

        int size = highExclusive - low;
        boolean[] isPrime = new boolean[size];
        for (int i = 0; i < size; i++)
            isPrime[i] = true;

        for (int p : basePrimes) {
            long start = ((long) low + p - 1) / p * p;
            long pp = (long) p * p;
            if (start < pp)
                start = pp;
            for (long x = start; x < highExclusive; x += p) {
                isPrime[(int) (x - low)] = false;
            }
        }

        if (low == 0) {
            isPrime[0] = false;
            if (size > 1)
                isPrime[1] = false;
        } else if (low == 1) {
            isPrime[0] = false;
        }

        List<Integer> primes = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            if (isPrime[i])
                primes.add(low + i);
        }
        return primes;
    }

    static long ceilKSqrtN(int n, int k) {
        long target = (long) k * k * n;
        long x = (long) Math.sqrt(target);
        if (x * x == target)
            return x;
        return x + 1;
    }

    static long nCkMod(int n, int k, int[] fact, int[] invfact) {
        if (k < 0 || k > n)
            return 0;
        return ((long) fact[n] * invfact[k] % kMod) * invfact[n - k] % kMod;
    }

    static long gMod(int n, int[] fact, int[] invfact) {
        int kMax = (int) Math.sqrt(n);
        long total = 0;
        for (int k = 0; k <= kMax; k++) {
            long ceilTerm = ceilKSqrtN(n, k);
            int m = n - (int) ceilTerm + k;
            if (m < k)
                continue;
            total = (total + nCkMod(m, k, fact, invfact)) % kMod;
        }
        return total;
    }

    static long solveSumPrimes(int lowExclusive, int highExclusive) {
        int maxN = highExclusive - 1;
        int[] fact = new int[maxN + 1];
        int[] invfact = new int[maxN + 1];

        fact[0] = 1;
        for (int i = 1; i <= maxN; i++) {
            fact[i] = (int) (((long) fact[i - 1] * i) % kMod);
        }

        invfact[maxN] = (int) modPow(fact[maxN], kMod - 2, kMod);
        for (int i = maxN; i >= 1; i--) {
            invfact[i - 1] = (int) (((long) invfact[i] * i) % kMod);
        }

        List<Integer> primes = segmentedPrimes(lowExclusive + 1, highExclusive);
        long total = 0;
        for (int p : primes) {
            total = (total + gMod(p, fact, invfact)) % kMod;
        }
        return total;
    }

    public static void main(String[] args) {
        int low = 10000000;
        int high = 10010000;
        System.out.println(solveSumPrimes(low, high));
    }
}
