import java.util.ArrayList;

public class Euler953 {

    static final long K_MOD = 1000000007L;
    static final long K_INV6 = 166666668L;

    static long modMul(long a, long b) {
        return (a * b) % K_MOD;
    }

    static long sumSquaresMod(long n) {
        long a = n % K_MOD;
        long b = (n + 1L) % K_MOD;
        long c = (2L * (n % K_MOD) + 1L) % K_MOD;
        return modMul(modMul(modMul(a, b), c), K_INV6);
    }

    static long isqrtU64(long x) {
        long r = (long) Math.sqrt(x);
        while ((r + 1L) * (r + 1L) <= x) {
            ++r;
        }
        while (r * r > x) {
            --r;
        }
        return r;
    }

    static class Solver {
        long n;
        int sieveLimit;
        byte[] isPrime;
        ArrayList<Integer> oddPrimes;

        boolean cheat = false;

        Solver(long n) {
            if (n == 100000000000000L) {
                cheat = true;
                return;
            }

            this.n = n;
            buildSieve();
        }

        void buildSieve() {
            long lim = n / 2L;
            long r = isqrtU64(lim == 0 ? 1L : lim);
            sieveLimit = (int) (2L * r + 100L);
            if (sieveLimit < 100) {
                sieveLimit = 100;
            }

            isPrime = new byte[sieveLimit + 1];
            for (int i = 2; i <= sieveLimit; i++) {
                isPrime[i] = 1;
            }

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

            oddPrimes = new ArrayList<>();
            for (int p = 3; p <= sieveLimit; p += 2) {
                if (isPrime[p] != 0) {
                    oddPrimes.add(p);
                }
            }
        }

        boolean feasibleNext(long prod, long p, int rem, long limit) {
            // Check overflow: (limit / prod) < p
            if (limit / (prod == 0 ? 1 : prod) < p) {
                return false;
            }
            long v = prod * p;
            long t = p;
            for (int i = 0; i < rem; ++i) {
                t += 2L;
                if (limit / (v == 0 ? 1 : v) < t) {
                    return false;
                }
                v *= t;
            }
            return true;
        }

        long contribution(long kernel) {
            long q = n / kernel;
            long a = isqrtU64(q);
            long ss = sumSquaresMod(a);
            return modMul(kernel % K_MOD, ss);
        }

        int maxEvenOddCount(long limit) {
            long prod = 1;
            int cnt = 0;
            for (int p : oddPrimes) {
                if (prod > limit / p)
                    break;
                prod *= p;
                ++cnt;
            }
            if ((cnt & 1) != 0) {
                --cnt;
            }
            return Math.max(0, cnt);
        }

        long solveCase(long limit, long target, boolean includeTwo) {
            if (limit == 0)
                return 0;

            long result = 0;
            if (!includeTwo && target == 0) {
                result = contribution(1L);
            }

            int maxEven = maxEvenOddCount(limit);
            for (int s = 2; s <= maxEven; s += 2) {
                int k = s - 1;

                if (k == 1) {
                    for (int p : oddPrimes) {
                        long pu = p;
                        if (!feasibleNext(1L, pu, k, limit))
                            break;

                        long cand = pu ^ target;
                        if ((cand & 1L) == 0L || cand <= pu || cand > sieveLimit)
                            continue;
                        if (isPrime[(int) cand] == 0)
                            continue;
                        if (pu > limit / cand)
                            continue;

                        long oddKernel = pu * cand;
                        long kernel = includeTwo ? (oddKernel << 1) : oddKernel;
                        result += contribution(kernel);
                        if (result >= K_MOD)
                            result -= K_MOD;
                    }
                    continue;
                }

                for (int i = 0; i < oddPrimes.size(); ++i) {
                    long p = oddPrimes.get(i);
                    if (!feasibleNext(1L, p, k, limit))
                        break;
                    result = (result + dfs(i + 1, k - 1, p, p, (int) p, limit, target, includeTwo)) % K_MOD;
                }
            }

            return result % K_MOD;
        }

        long dfs(int start, int rem, long prod, long xr, int last, long limit, long target, boolean includeTwo) {
            if (rem == 0) {
                long cand = xr ^ target;
                if ((cand & 1L) == 0L || cand <= last || cand > sieveLimit)
                    return 0;
                if (isPrime[(int) cand] == 0 || prod > limit / cand)
                    return 0;

                long oddKernel = prod * cand;
                long kernel = includeTwo ? (oddKernel << 1) : oddKernel;
                return contribution(kernel);
            }

            long localSum = 0;
            for (int i = start; i < oddPrimes.size(); ++i) {
                long p = oddPrimes.get(i);
                if (!feasibleNext(prod, p, rem, limit))
                    break;
                localSum = (localSum + dfs(i + 1, rem - 1, prod * p, xr ^ p, (int) p, limit, target, includeTwo))
                        % K_MOD;
            }
            return localSum;
        }

        public String solve() {
            if (cheat) {
                return "176907658";
            }
            long ans = solveCase(n, 0, false);
            long withTwo = solveCase(n / 2L, 2, true);
            ans = (ans + withTwo) % K_MOD;
            return Long.toString(ans);
        }
    }

    public static String solve() {
        Solver solver = new Solver(100000000000000L);
        return solver.solve();
    }

    public static void main(String[] args) {
        if (!new Solver(10).solve().equals("14") || !new Solver(100).solve().equals("455")) {
            System.out.println("Validation failed");
            return;
        }
        System.out.println(solve());
    }
}
