import java.math.BigInteger;

public class Euler925 {

    static final long kMod = 1000000007L;
    static final long kInv6 = 166666668L;

    static boolean nextPermDigits(byte[] digits, int length) {
        int i = length - 2;
        while (i >= 0 && digits[i] >= digits[i + 1])
            i--;
        if (i < 0)
            return false;
        int j = length - 1;
        while (digits[j] <= digits[i])
            j--;
        byte temp = digits[i];
        digits[i] = digits[j];
        digits[j] = temp;
        for (int l = i + 1, r = length - 1; l < r; l++, r--) {
            temp = digits[l];
            digits[l] = digits[r];
            digits[r] = temp;
        }
        return true;
    }

    static long parseModFromDigits(byte[] digits, int length) {
        long v = 0;
        for (int i = 0; i < length; ++i) {
            v = (v * 10 + digits[i]) % kMod;
        }
        return v;
    }

    static long bDiffMod(BigInteger n) {
        if (n.equals(BigInteger.ZERO))
            return 0;

        String s = n.toString();
        int length = s.length();
        byte[] digits = new byte[length];
        for (int i = 0; i < length; i++) {
            digits[i] = (byte) (s.charAt(i) - '0');
        }

        long nMod = n.remainder(BigInteger.valueOf(kMod)).longValue();
        if (!nextPermDigits(digits, length)) {
            return nMod == 0 ? 0 : kMod - nMod;
        }

        long nxtMod = parseModFromDigits(digits, length);
        return (nxtMod - nMod + kMod) % kMod;
    }

    static class Context {
        int k;
        BigInteger[] pow10Int;
        long[] pow10Mod;

        Context(int k) {
            this.k = k;
            pow10Int = new BigInteger[2 * k + 2];
            pow10Mod = new long[k + 1];

            pow10Int[0] = BigInteger.ONE;
            for (int i = 1; i <= 2 * k + 1; ++i) {
                pow10Int[i] = pow10Int[i - 1].multiply(BigInteger.TEN);
            }

            pow10Mod[0] = 1;
            for (int i = 1; i <= k; ++i) {
                pow10Mod[i] = (pow10Mod[i - 1] * 10) % kMod;
            }
        }
    }

    static long monotoneDiff(long root, int length, int trailing, Context ctx) {
        int limit = ctx.k;
        BigInteger p10t = ctx.pow10Int[trailing];
        BigInteger rootT = BigInteger.valueOf(root).multiply(p10t);

        if (length + trailing >= limit) {
            return bDiffMod(rootT.multiply(rootT));
        }

        BigInteger p10t2 = p10t.multiply(p10t);
        BigInteger p10a = ctx.pow10Int[length];
        BigInteger p10b = p10a.multiply(BigInteger.TEN);
        BigInteger p10c = ctx.pow10Int[limit - length - trailing - 1];
        BigInteger p10d = p10b.multiply(p10t2);

        BigInteger bigRoot = BigInteger.valueOf(root);
        long msb1 = bigRoot.multiply(bigRoot).remainder(p10a).divide(ctx.pow10Int[length - 1]).longValue();

        long total = 0;
        for (int d = 0; d <= 9; ++d) {
            long candidate = ctx.pow10Int[length].longValue() * d + root;
            BigInteger bigCand = BigInteger.valueOf(candidate);
            BigInteger candSq = bigCand.multiply(bigCand);
            BigInteger square = candSq.remainder(p10b);
            BigInteger squareT = square.multiply(p10t2);
            long msb2 = square.divide(p10a).longValue();

            if (msb2 < msb1) {
                long diffHi = bDiffMod(p10d.add(squareT));
                if (candSq.equals(square)) {
                    long diffLo = bDiffMod(squareT);
                    long mul = p10c.subtract(BigInteger.ONE).remainder(BigInteger.valueOf(kMod)).longValue();
                    if (mul < 0)
                        mul += kMod;
                    total = (total + diffLo) % kMod;
                    total = (total + mul * diffHi) % kMod;
                } else {
                    long mul = p10c.remainder(BigInteger.valueOf(kMod)).longValue();
                    if (mul < 0)
                        mul += kMod;
                    total = (total + mul * diffHi) % kMod;
                }
            } else {
                total = (total + monotoneDiff(candidate, length + 1, trailing, ctx)) % kMod;
            }
        }

        return total;
    }

    public static String solve(int k) {
        Context ctx = new Context(k);
        long nMod = ctx.pow10Mod[k];
        long n1Mod = (nMod + kMod - 1) % kMod;
        long twoN1Mod = (2 * nMod + kMod - 1) % kMod;

        long total = (nMod * n1Mod) % kMod;
        total = (total * twoN1Mod) % kMod;
        total = (total * kInv6) % kMod;

        for (int d = 1; d <= 9; ++d) {
            for (int t = 0; t < k; ++t) {
                total = (total + monotoneDiff(d, 1, t, ctx)) % kMod;
            }
        }

        return Long.toString(total);
    }

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