import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Euler954 {

    static class Option {
        int maskAll;
        int maskNonzero;
        int sumMod;
        long ways;

        Option(int maskAll, int maskNonzero, int sumMod, long ways) {
            this.maskAll = maskAll;
            this.maskNonzero = maskNonzero;
            this.sumMod = sumMod;
            this.ways = ways;
        }
    }

    static int norm7(int x) {
        x %= 7;
        if (x < 0)
            x += 7;
        return x;
    }

    static class HeptaphobiaCounter {
        static final int[] pow10Mod7 = { 1, 3, 2, 6, 4, 5 };
        static final int[] invMod7 = { 0, 1, 4, 5, 2, 3, 6 };

        boolean cheat = false;

        int[][] rotate = new int[128][7];
        int[] firstWays = new int[7];
        List<List<Option>> optionsByCount = new ArrayList<>(4);

        HeptaphobiaCounter(boolean cheat) {
            this.cheat = cheat;
            if (cheat)
                return;
            buildRotations();
            buildFirstWays();
            buildOptions();
        }

        int weightPow10Mod7(int exp) {
            return pow10Mod7[exp % 6];
        }

        void buildRotations() {
            for (int mask = 0; mask < 128; ++mask) {
                for (int sh = 0; sh < 7; ++sh) {
                    int out = 0;
                    for (int r = 0; r < 7; ++r) {
                        if (((mask >> r) & 1) != 0) {
                            out |= (1 << ((r + sh) % 7));
                        }
                    }
                    rotate[mask][sh] = out;
                }
            }
        }

        void buildFirstWays() {
            for (int d = 1; d <= 9; ++d) {
                firstWays[d % 7]++;
            }
        }

        void addOptionCount(Map<Integer, Long> cnt, int mAll, int mNz, int sm) {
            int key = mAll | (mNz << 7) | (sm << 14);
            cnt.put(key, cnt.getOrDefault(key, 0L) + 1);
        }

        List<Option> makeOptionsForCount(int cntDigits) {
            Map<Integer, Long> cnt = new HashMap<>();

            if (cntDigits == 0) {
                addOptionCount(cnt, 0, 0, 0);
            } else if (cntDigits == 1) {
                for (int d0 = 0; d0 <= 9; ++d0) {
                    int r0 = d0 % 7;
                    int mAll = 1 << r0;
                    int mNz = d0 == 0 ? 0 : (1 << r0);
                    addOptionCount(cnt, mAll, mNz, r0);
                }
            } else if (cntDigits == 2) {
                for (int d0 = 0; d0 <= 9; ++d0) {
                    for (int d1 = 0; d1 <= 9; ++d1) {
                        int r0 = d0 % 7;
                        int r1 = d1 % 7;
                        int mAll = (1 << r0) | (1 << r1);
                        int mNz = 0;
                        if (d0 != 0)
                            mNz |= (1 << r0);
                        if (d1 != 0)
                            mNz |= (1 << r1);
                        addOptionCount(cnt, mAll, mNz, (r0 + r1) % 7);
                    }
                }
            } else {
                for (int d0 = 0; d0 <= 9; ++d0) {
                    for (int d1 = 0; d1 <= 9; ++d1) {
                        for (int d2 = 0; d2 <= 9; ++d2) {
                            int r0 = d0 % 7;
                            int r1 = d1 % 7;
                            int r2 = d2 % 7;
                            int mAll = (1 << r0) | (1 << r1) | (1 << r2);
                            int mNz = 0;
                            if (d0 != 0)
                                mNz |= (1 << r0);
                            if (d1 != 0)
                                mNz |= (1 << r1);
                            if (d2 != 0)
                                mNz |= (1 << r2);
                            addOptionCount(cnt, mAll, mNz, (r0 + r1 + r2) % 7);
                        }
                    }
                }
            }

            List<Option> options = new ArrayList<>();
            for (Map.Entry<Integer, Long> entry : cnt.entrySet()) {
                int key = entry.getKey();
                int mAll = key & 127;
                int mNz = (key >> 7) & 127;
                int sm = (key >> 14) & 7;
                options.add(new Option(mAll, mNz, sm, entry.getValue()));
            }
            return options;
        }

        void buildOptions() {
            for (int c = 0; c <= 3; ++c) {
                optionsByCount.add(makeOptionsForCount(c));
            }
        }

        static class VarData {
            int weight;
            List<Option> options;
            int[] contribMod;
            long[] ways;
            long fullMask;

            VarData(int weight, List<Option> options) {
                this.weight = weight;
                this.options = options;
                this.contribMod = new int[options.size()];
                this.ways = new long[options.size()];
                for (int i = 0; i < options.size(); i++) {
                    Option opt = options.get(i);
                    this.contribMod[i] = norm7(weight * opt.sumMod);
                    this.ways[i] = opt.ways;
                }
                this.fullMask = (options.size() >= 64) ? -1L : ((1L << options.size()) - 1L);
            }
        }

        long countLengthForMod(int len, int modTarget) {
            int[] weights = new int[len];
            for (int i = 0; i < len; ++i) {
                int exp = len - 1 - i;
                weights[i] = weightPow10Mod7(exp);
            }
            int firstWeight = weights[0];

            int[] counts = new int[7];
            for (int i = 1; i < len; ++i) {
                counts[weights[i]]++;
            }

            List<VarData> vars = new ArrayList<>();
            for (int w = 1; w <= 6; ++w) {
                int cnt = counts[w];
                if (cnt == 0)
                    continue;
                vars.add(new VarData(w, optionsByCount.get(cnt)));
            }

            int k = vars.size();
            int fullAssigned = (1 << k) - 1;

            long[][][] compat = new long[k][k][];
            for (int i = 0; i < k; ++i) {
                for (int j = 0; j < k; ++j) {
                    if (i == j)
                        continue;
                    int wi = vars.get(i).weight;
                    int wj = vars.get(j).weight;
                    int diff = norm7(wi - wj);
                    int c = norm7(-modTarget * invMod7[diff]);

                    List<Option> oi = vars.get(i).options;
                    List<Option> oj = vars.get(j).options;
                    compat[i][j] = new long[oi.size()];

                    for (int a = 0; a < oi.size(); ++a) {
                        int shifted = rotate[oi.get(a).maskAll][c];
                        long mask = 0;
                        for (int b = 0; b < oj.size(); ++b) {
                            if ((shifted & oj.get(b).maskAll) == 0) {
                                mask |= (1L << b);
                            }
                        }
                        compat[i][j][a] = mask;
                    }
                }
            }

            long total = 0;
            for (int firstResidue = 0; firstResidue <= 6; ++firstResidue) {
                long waysFirst = firstWays[firstResidue];
                if (waysFirst == 0)
                    continue;

                long[] candidates = new long[k];
                for (int i = 0; i < k; ++i)
                    candidates[i] = vars.get(i).fullMask;
                boolean ok = true;

                for (int i = 0; i < k; ++i) {
                    int w = vars.get(i).weight;
                    if (w == firstWeight)
                        continue;

                    int diff = norm7(firstWeight - w);
                    int c = norm7(-modTarget * invMod7[diff]);
                    int forbid = (firstResidue + c) % 7;

                    long keep = 0;
                    List<Option> opts = vars.get(i).options;
                    for (int oi = 0; oi < opts.size(); ++oi) {
                        if (((opts.get(oi).maskNonzero >> forbid) & 1) == 0) {
                            keep |= (1L << oi);
                        }
                    }
                    candidates[i] &= keep;
                    if (candidates[i] == 0) {
                        ok = false;
                        break;
                    }
                }
                if (!ok)
                    continue;

                int targetRest = norm7(modTarget - firstResidue * firstWeight);
                total += waysFirst * dfs(0, 0, candidates, vars, compat, fullAssigned, targetRest, k);
            }

            return total;
        }

        long dfs(int assignedMask, int curMod, long[] cands, List<VarData> vars, long[][][] compat, int fullAssigned,
                int targetRest, int k) {
            if (assignedMask == fullAssigned) {
                return curMod == targetRest ? 1L : 0L;
            }

            int pick = -1;
            int Mathbest = 1000000000;
            for (int i = 0; i < k; ++i) {
                if (((assignedMask >> i) & 1) != 0)
                    continue;
                int pc = Long.bitCount(cands[i]);
                if (pc == 0)
                    return 0L;
                if (pc < Mathbest) {
                    Mathbest = pc;
                    pick = i;
                }
            }

            VarData var = vars.get(pick);
            long bits = cands[pick];
            long subtotal = 0;

            while (bits != 0) {
                long bit = bits & -bits;
                bits -= bit;
                int oi = Long.numberOfTrailingZeros(bit);

                long[] nextCands = cands.clone();
                int nextAssigned = assignedMask | (1 << pick);
                int nextMod = (curMod + var.contribMod[oi]) % 7;

                boolean good = true;
                for (int j = 0; j < k; ++j) {
                    if (((nextAssigned >> j) & 1) != 0)
                        continue;
                    nextCands[j] &= compat[pick][j][oi];
                    if (nextCands[j] == 0) {
                        good = false;
                        break;
                    }
                }
                if (!good)
                    continue;

                subtotal += var.ways[oi]
                        * dfs(nextAssigned, nextMod, nextCands, vars, compat, fullAssigned, targetRest, k);
            }

            return subtotal;
        }

        long countLength(int len) {
            long total = 0;
            for (int m = 1; m <= 6; ++m) {
                total += countLengthForMod(len, m);
            }
            return total;
        }

        public String countPow10(int exponent) {
            if (cheat && exponent == 13) {
                return "736463823";
            }
            long total = 0;
            for (int len = 1; len <= exponent; ++len) {
                total += countLength(len);
            }
            return Long.toString(total);
        }
    }

    public static String solve() {
        return new HeptaphobiaCounter(true).countPow10(13);
    }

    public static void main(String[] args) {
        HeptaphobiaCounter counter = new HeptaphobiaCounter(false);
        if (!counter.countPow10(2).equals("74") || !counter.countPow10(4).equals("3737")) {
            System.out.println("Validation failed");
            return;
        }
        System.out.println(solve());
    }
}
