module main; // https://kmjp.hatenablog.jp/entry/2015/12/09/0900 より // claude ai より // 数え上げ、剰余 import std; immutable MOD = 10L ^^ 9 + 7; long[] p10; long[][][] memo; // 多次元配列をある値で埋める void fill(A, T)(ref A a, T value) if (isArray!A) { alias E = ElementType!A; static if (isArray!E) { foreach (ref e; a) fill(e, value); } else { a[] = value; } } long dfs(char[] S, int d, int m, int lead) { int len = S.length.to!int; if (d >= len) return m == 0; if (memo[d][m][lead] >= 0) return memo[d][m][lead]; long ret = 0; if (lead == 1) { foreach (i; 0 .. S[d] - '0') { if (i == 3) ret += p10[len - 1 - d]; else ret += dfs(S, d + 1, (m + i) % 3, 0); } if (S[d] == '3') { long pat = 0; foreach (i; d + 1 .. len) pat = (pat * 10 + (S[i] - '0')) % MOD; ret += pat + 1; } else { ret += dfs(S, d + 1, (m + S[d] - '0') % 3, 1); } } else { foreach (i; 0 .. 10) { if (i == 3) ret += p10[len - 1 - d]; else ret += dfs(S, d + 1, (m + i) % 3, 0); } } return memo[d][m][lead] = ret % MOD; } // 文字列で表された数を1減らす void dec(ref char[] A) { A.reverse; foreach (ref r; A) { if (r != '0') { r--; break; } r = '9'; } if (A.length > 1 && A.back == '0') A.length -= 1; A.reverse; } int greed(int v, int p) { int ret = 0; foreach (i; 1 .. v + 1) { if (i % p == 0) continue; int j = i; while (j) { if (j % 10 == 3) break; j /= 10; } if (j || (i % 3 == 0)) ret++; } return ret; } long calc(char[] S, long P) { auto dp = new long[][](2, 3), t = new long[](2); if (S.length <= 5) return greed(S.to!int, P.to!int); long ret = 0; int low = S[$ - 5 .. $].to!int; S = S[0 .. $ - 5]; foreach (j; 0 .. 2) { fill(memo, -1); foreach (i; 0 .. 3) dp[j][i] = dfs(S, 0, i, 1); foreach (r; S) t[j] = (t[j] * 10 + r - '0') % MOD; t[j]++; dec(S); } foreach (i; 0 .. 100_000) { int v = i; if (i % P == 0) continue; while (v) { if (v % 10 == 3) break; v /= 10; } if (v) ret += t[i > low]; else ret += dp[i > low][i % 3]; } return ret % MOD; } void main() { // 入力 char[] A, B; long P; readln.chomp.formattedRead("%s %s %d", A, B, P); // 答えの計算 p10 = 1L.recurrence!((a,n) => a[n-1] * 10 % MOD).take(B.length + 1).array; memo = new long[][][](B.length + 1, 3, 2); dec(A); // 答えの出力 writeln((calc(B, P) + MOD - calc(A, P)) % MOD); }