import java.util.*;

public class Euler413 {
    public static String solve() {
        long total = 0;
        for (int n = 1; n <= 19; n++)
            total += countForLength(n);
        return String.valueOf(total);
    }

    static long countForLength(int n) {
        int[] digitMod = new int[10];
        for (int d = 0; d < 10; d++)
            digitMod[d] = d % n;
        int[][] nextRem = new int[10][n];
        for (int d = 0; d < 10; d++)
            for (int r = 0; r < n; r++)
                nextRem[d][r] = (10 * r + digitMod[d]) % n;

        int pow3n = 1;
        for (int i = 0; i < n; i++)
            pow3n *= 3;

        Map<Integer, Long> curr0 = new HashMap<>(), curr1 = new HashMap<>();
        for (int d = 1; d <= 9; d++) {
            int[] counts = new int[n];
            counts[digitMod[d]] = 1;
            int key = encode(counts, n);
            if (counts[0] == 0)
                curr0.merge(key, 1L, Long::sum);
            else if (counts[0] == 1)
                curr1.merge(key, 1L, Long::sum);
        }

        for (int pos = 2; pos <= n; pos++) {
            Map<Integer, Long> next0 = new HashMap<>(), next1 = new HashMap<>();
            for (var entry : curr0.entrySet()) {
                int[] counts = decode(entry.getKey(), n);
                long ways = entry.getValue();
                for (int d = 0; d < 10; d++) {
                    int[] nc = new int[n];
                    for (int r = 0; r < n; r++) {
                        int c = counts[r];
                        if (c == 0)
                            continue;
                        int nr = nextRem[d][r];
                        nc[nr] = Math.min(2, nc[nr] + c);
                    }
                    int dr = digitMod[d];
                    nc[dr] = Math.min(2, nc[dr] + 1);
                    int nk = encode(nc, n);
                    if (nc[0] == 0)
                        next0.merge(nk, ways, Long::sum);
                    else if (nc[0] == 1)
                        next1.merge(nk, ways, Long::sum);
                }
            }
            for (var entry : curr1.entrySet()) {
                int[] counts = decode(entry.getKey(), n);
                long ways = entry.getValue();
                for (int d = 0; d < 10; d++) {
                    int[] nc = new int[n];
                    for (int r = 0; r < n; r++) {
                        int c = counts[r];
                        if (c == 0)
                            continue;
                        int nr = nextRem[d][r];
                        nc[nr] = Math.min(2, nc[nr] + c);
                    }
                    int dr = digitMod[d];
                    nc[dr] = Math.min(2, nc[dr] + 1);
                    if (nc[0] == 0) {
                        int nk = encode(nc, n);
                        next1.merge(nk, ways, Long::sum);
                    }
                }
            }
            curr0 = next0;
            curr1 = next1;
        }
        long sum = 0;
        for (long v : curr1.values())
            sum += v;
        return sum;
    }

    static int encode(int[] counts, int n) {
        int key = 0, mul = 1;
        for (int i = 0; i < n; i++) {
            key += counts[i] * mul;
            mul *= 3;
        }
        return key;
    }

    static int[] decode(int key, int n) {
        int[] counts = new int[n];
        for (int i = 0; i < n; i++) {
            counts[i] = key % 3;
            key /= 3;
        }
        return counts;
    }

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