import java.util.HashMap;

public class Euler847 {
    static final long MOD = 1000000007L;

    static long modAdd(long a, long b) {
        long r = a + b;
        if (r >= MOD)
            r -= MOD;
        return r;
    }

    static long modSub(long a, long b) {
        long r = a - b;
        if (r < 0)
            r += MOD;
        return r;
    }

    static long modMul(long a, long b) {
        long aMod = (a % MOD + MOD) % MOD;
        long bMod = (b % MOD + MOD) % MOD;
        return (aMod * bMod) % MOD;
    }

    static long modPow(long a, long e) {
        long r = 1 % MOD;
        long x = (a % MOD + MOD) % MOD;
        while (e > 0) {
            if ((e & 1) == 1)
                r = modMul(r, x);
            x = modMul(x, x);
            e >>= 1;
        }
        return r;
    }

    static final long INV2 = modPow(2, MOD - 2);
    static final long INV6 = modPow(6, MOD - 2);

    static long sum1Mod(long n) {
        if (n < 0)
            return 0;
        long nMod = n % MOD;
        return modMul(modMul(nMod, (nMod + 1) % MOD), INV2);
    }

    static long sum2Mod(long n) {
        if (n < 0)
            return 0;
        long nMod = n % MOD;
        long n1 = (nMod + 1) % MOD;
        long twoN1 = (modMul(2, nMod) + 1) % MOD;
        return modMul(modMul(modMul(nMod, n1), twoN1), INV6);
    }

    static long sum1RangeMod(long l, long r) {
        if (l > r)
            return 0;
        return modSub(sum1Mod(r), sum1Mod(l - 1));
    }

    static long sum2RangeMod(long l, long r) {
        if (l > r)
            return 0;
        return modSub(sum2Mod(r), sum2Mod(l - 1));
    }

    static long sumPairMod(long l, long r, long N) {
        if (l > r)
            return 0;
        long cnt = r - l + 1;
        long S1 = sum1RangeMod(l, r);
        long S2 = sum2RangeMod(l, r);
        long sumSPlus = modAdd(S1, cnt % MOD);
        long sumS2Plus = modAdd(S2, S1);
        return modSub(modMul((N + 1) % MOD, sumSPlus), sumS2Plus);
    }

    static long sumTriMod(long l, long r) {
        if (l > r)
            return 0;
        long cnt = r - l + 1;
        long S1 = sum1RangeMod(l, r);
        long S2 = sum2RangeMod(l, r);
        long total = modAdd(S2, modAdd(modMul(3, S1), modMul(2, cnt % MOD)));
        return modMul(total, INV2);
    }

    static long sumM1SqMod(long l, long r, long D) {
        if (l > r)
            return 0;
        long uLow = D - r + 1;
        long uHigh = D - l + 1;
        return sum2RangeMod(uLow, uHigh);
    }

    static long sumTT1Mod(long t0, long step, long n) {
        if (n <= 0)
            return 0;
        long nMod = n % MOD;
        long n1Mod = (n - 1) % MOD;
        if (n1Mod < 0)
            n1Mod += MOD;
        long sumI = modMul(modMul(nMod, n1Mod), INV2);
        long twoN1 = (modMul(2, n1Mod) + 1) % MOD;
        long sumI2 = modMul(modMul(modMul(nMod, n1Mod), twoN1), INV6);

        long t0Mod = (t0 % MOD + MOD) % MOD;
        long stepMod = (step % MOD + MOD) % MOD;

        long sumT = modAdd(modMul(nMod, t0Mod), modMul(stepMod, sumI));
        long t0Sq = modMul(t0Mod, t0Mod);
        long term1 = modMul(nMod, t0Sq);
        long term2 = modMul(modMul(modMul(2, t0Mod), stepMod), sumI);
        long term3 = modMul(modMul(stepMod, stepMod), sumI2);
        long sumT2 = modAdd(term1, modAdd(term2, term3));

        return modMul(modAdd(sumT2, sumT), INV2);
    }

    static long tMod(long x) {
        if (x < 0)
            return 0;
        long xm = x % MOD;
        return modMul(modMul(modMul((xm + 1) % MOD, (xm + 2) % MOD), (xm + 3) % MOD), INV6);
    }

    static long countWithinCubeMod(long N, long D) {
        if (N < 0)
            return 0;
        if (N > 2 * D)
            N = 2 * D;

        long U;
        if (N <= D) {
            U = tMod(N);
        } else {
            U = modSub(tMod(N), modMul(3, tMod(N - D - 1)));
        }

        long A;
        if (N <= D) {
            A = sumPairMod(0, N, N);
        } else {
            long s1 = N - D;
            long part1 = modMul((D + 1) % MOD, modMul(modMul((s1 + 1) % MOD, (s1 + 2) % MOD), INV2));
            long part2 = sumPairMod(s1 + 1, D, N);
            A = modAdd(part1, part2);
        }

        long AB;
        if (N <= D) {
            AB = sumTriMod(0, N);
        } else {
            long a0 = 2 * D - N;
            long mid1 = sumM1SqMod(0, a0 - 1, D);
            long mid2 = sumTT1Mod(a0, -1, a0);
            long mid = modSub(mid1, mid2);
            long full = sumM1SqMod(a0, D, D);
            AB = modAdd(mid, full);
        }

        long ABC;
        if (N <= D) {
            ABC = sumTriMod(0, N);
        } else {
            long A1 = N - D;
            long aHalf = D / 2;
            long total = 0;

            long r1End = Math.min(A1, aHalf - 1);
            if (r1End >= 0) {
                long mid1 = sumM1SqMod(0, r1End, D);
                long n = r1End + 1;
                long mid2 = sumTT1Mod(D, -2, n);
                total = modAdd(total, modSub(mid1, mid2));
            }

            long r1FullStart = Math.max(0L, aHalf);
            if (r1FullStart <= A1) {
                total = modAdd(total, sumM1SqMod(r1FullStart, A1, D));
            }

            long l2 = A1 + 1;
            if (l2 <= D) {
                long a0 = 2 * D - N;
                long r2End = Math.min(a0 - 1, D);
                if (l2 <= r2End) {
                    long mid1 = sumM1SqMod(l2, r2End, D);
                    long n = r2End - l2 + 1;
                    long mid2 = sumTT1Mod(a0 - l2, -1, n);
                    total = modAdd(total, modSub(mid1, mid2));
                }

                long lFull = Math.max(l2, a0);
                if (lFull <= D) {
                    total = modAdd(total, sumM1SqMod(lFull, D, D));
                }
            }
            ABC = total;
        }

        return modSub(modAdd(modSub(U, modMul(3, A)), modMul(3, AB)), ABC);
    }

    static HashMap<String, Long> memo = new HashMap<>();

    static long hardCountMod(int k, long N) {
        if (N < 0)
            return 0;
        if (k == 1) {
            if (N <= 2)
                return 0;
            return modSub(tMod(N), tMod(2));
        }
        if (N > (1L << k))
            N = 1L << k;

        String key = k + "_" + N;
        if (memo.containsKey(key))
            return memo.get(key);

        long D = 1L << (k - 1);
        long res;
        if (N <= D) {
            res = countWithinCubeMod(N, D);
        } else {
            res = modAdd(countWithinCubeMod(N, D), modMul(3, hardCountMod(k - 1, N - D)));
        }

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

    static long sumCRange(long L, long R) {
        if (L > R)
            return 0;
        long cnt = R - L + 1;
        long S1 = sum1RangeMod(L, R);
        long S2 = sum2RangeMod(L, R);
        long total = modAdd(S2, modAdd(modMul(3, S1), modMul(2, cnt % MOD)));
        return modMul(total, INV2);
    }

    static long computeH(long N) {
        if (N <= 1)
            return 0;
        int maxK = 64 - Long.numberOfLeadingZeros(N - 1);

        long base = 0;
        for (int k = 1; k <= maxK; ++k) {
            long L = (1L << (k - 1)) + 1;
            long R = Math.min(N, 1L << k);
            if (L > R)
                continue;
            long sumC = sumCRange(L, R);
            base = modAdd(base, modMul(k % MOD, sumC));
        }

        memo.clear();
        long extra = 0;
        for (int k = 1; k <= maxK; ++k) {
            long X = Math.min(N, 1L << k);
            extra = modAdd(extra, hardCountMod(k, X));
        }

        return modAdd(base, extra);
    }

    public static String solve() {
        long N = 0;
        for (int i = 0; i < 19; ++i) {
            N = N * 10 + 1;
        }
        return Long.toString(computeH(N));
    }

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