import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

public class Euler465 {

    static final long MOD = 1000000007L;

    static long modPow(long base, java.math.BigInteger exp) {
        if (exp.equals(java.math.BigInteger.ZERO))
            return 1;
        base %= MOD;
        if (base == 0)
            return 0;
        long result = 1;

        java.math.BigInteger e = exp;
        while (e.compareTo(java.math.BigInteger.ZERO) > 0) {
            if (e.testBit(0))
                result = (result * base) % MOD;
            base = (base * base) % MOD;
            e = e.shiftRight(1);
        }
        return result;
    }

    static class PhiSummatory {
        long limit;
        long[] prefix;
        Map<Long, java.math.BigInteger> memo;

        PhiSummatory(long n) {
            long lim = (long) Math.pow(n, 2.0 / 3.0);
            long kMinLimit = 1000000;
            long kMaxLimit = 10000000;
            if (lim < kMinLimit)
                lim = Math.min(n, kMinLimit);
            if (lim > kMaxLimit)
                lim = kMaxLimit;
            if (lim < 1)
                lim = 1;
            if (lim > n)
                lim = n;
            limit = lim;

            int len = (int) limit;
            int[] phi = new int[len + 1];
            int[] primes = new int[len / 10 + 10];
            int primesCount = 0;

            if (len >= 1)
                phi[1] = 1;
            for (int i = 2; i <= len; i++) {
                if (phi[i] == 0) {
                    phi[i] = i - 1;
                    primes[primesCount++] = i;
                }
                for (int j = 0; j < primesCount; j++) {
                    int p = primes[j];
                    long v = (long) p * i;
                    if (v > len)
                        break;
                    if (i % p == 0) {
                        phi[(int) v] = phi[i] * p;
                        break;
                    }
                    phi[(int) v] = phi[i] * (p - 1);
                }
            }

            prefix = new long[len + 1];
            for (int i = 1; i <= len; i++) {
                prefix[i] = prefix[i - 1] + phi[i];
            }

            memo = new HashMap<>();
        }

        java.math.BigInteger sum(long n) {
            if (n <= 0)
                return java.math.BigInteger.ZERO;
            if (n <= limit)
                return java.math.BigInteger.valueOf(prefix[(int) n]);

            java.math.BigInteger cached = memo.get(n);
            if (cached != null)
                return cached;

            java.math.BigInteger res = java.math.BigInteger.valueOf(n)
                    .multiply(java.math.BigInteger.valueOf(n + 1))
                    .divide(java.math.BigInteger.valueOf(2));

            long i = 2;
            while (i <= n) {
                long q = n / i;
                long j = n / q;
                java.math.BigInteger term = java.math.BigInteger.valueOf(j - i + 1).multiply(sum(q));
                res = res.subtract(term);
                i = j + 1;
            }

            memo.put(n, res);
            return res;
        }
    }

    static class RangeObj {
        long q;
        java.math.BigInteger count;
        long countMod;

        RangeObj(long q, java.math.BigInteger count) {
            this.q = q;
            this.count = count;
            this.countMod = count.remainder(java.math.BigInteger.valueOf(MOD)).longValue();
        }
    }

    static class Partial {
        long h = 1;
        long s1 = 0;
        long s2 = 0;
    }

    static Partial computePartial(List<RangeObj> ranges, int start, int end) {
        Partial out = new Partial();
        for (int i = start; i < end; i++) {
            RangeObj range = ranges.get(i);
            long base = (range.q + 1) % MOD;
            out.h = (out.h * modPow(base, range.count)) % MOD;

            long qMod = range.q % MOD;
            long q2 = (qMod * qMod) % MOD;

            out.s1 = (out.s1 + (range.countMod * qMod) % MOD) % MOD;
            out.s2 = (out.s2 + (range.countMod * q2) % MOD) % MOD;
        }
        return out;
    }

    static class WorkerTask extends RecursiveTask<Partial> {
        List<RangeObj> ranges;
        int start;
        int end;

        WorkerTask(List<RangeObj> ranges, int start, int end) {
            this.ranges = ranges;
            this.start = start;
            this.end = end;
        }

        @Override
        protected Partial compute() {
            return computePartial(ranges, start, end);
        }
    }

    public static String solve() {
        long n = 1;
        for (int i = 0; i < 13; i++)
            n *= 7;

        PhiSummatory phi = new PhiSummatory(n);
        List<RangeObj> ranges = new ArrayList<>();

        long r = 1;
        while (r <= n) {
            long q = n / r;
            long R = n / q;

            java.math.BigInteger sumPhi = phi.sum(R).subtract(phi.sum(r - 1));
            java.math.BigInteger count = sumPhi.multiply(java.math.BigInteger.valueOf(4));

            ranges.add(new RangeObj(q, count));
            r = R + 1;
        }

        int threads = Math.max(1, Runtime.getRuntime().availableProcessors());
        ForkJoinPool pool = new ForkJoinPool(threads);

        int numRanges = ranges.size();
        int chunk = (numRanges + threads - 1) / threads;
        List<WorkerTask> tasks = new ArrayList<>();

        for (int t = 0; t < threads; t++) {
            int start = t * chunk;
            int end = Math.min(numRanges, start + chunk);
            if (start < end) {
                tasks.add(new WorkerTask(ranges, start, end));
            }
        }

        List<Partial> partials = new ArrayList<>();
        if (tasks.size() > 1) {
            for (int i = 1; i < tasks.size(); i++) {
                tasks.get(i).fork();
            }
            partials.add(tasks.get(0).compute());
            for (int i = 1; i < tasks.size(); i++) {
                partials.add(tasks.get(i).join());
            }
        } else if (!tasks.isEmpty()) {
            partials.add(tasks.get(0).compute());
        }

        long h = 1;
        long s1 = 0;
        long s2 = 0;

        for (Partial part : partials) {
            h = (h * part.h) % MOD;
            s1 = (s1 + part.s1) % MOD;
            s2 = (s2 + part.s2) % MOD;
        }

        long result = (h * h % MOD - 1 - (2 * h % MOD * s1) % MOD + s2) % MOD;
        if (result < 0)
            result += MOD;

        return Long.toString(result);
    }

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