#include using namespace std; using ll = long long; const int MOD = 1e9 + 7; string decrement(string s) { int n = s.size(); int i = n - 1; while (i >= 0 && s[i] == '0') { s[i] = '9'; i--; } if (i == -1) return "0"; s[i]--; if (s[i] == '0' && i == 0) { s.erase(s.begin()); if (s.empty()) return "0"; } else if (s[i] < '0') { s[i] += 10; } return s; } struct DPResult { int aho; int aho_p; }; DPResult compute(const string &s, int P) { int n = s.size(); vector digits(n); for (int i = 0; i < n; ++i) digits[i] = s[i] - '0'; // Compute aho vector>> dp_prev_aho(2, vector>(3, vector(2, 0))); dp_prev_aho[1][0][0] = 1; for (int i = 0; i < n; ++i) { int d = digits[i]; vector>> dp_next_aho(2, vector>(3, vector(2, 0))); for (int tight = 0; tight < 2; ++tight) { for (int sm = 0; sm < 3; ++sm) { for (int ht = 0; ht < 2; ++ht) { if (dp_prev_aho[tight][sm][ht] == 0) continue; int max_digit = (tight) ? d : 9; for (int next_d = 0; next_d <= max_digit; ++next_d) { int new_tight = (tight && (next_d == max_digit)) ? 1 : 0; int new_sm = (sm + next_d) % 3; int new_ht = ht || (next_d == 3); dp_next_aho[new_tight][new_sm][new_ht] = (dp_next_aho[new_tight][new_sm][new_ht] + dp_prev_aho[tight][sm][ht]) % MOD; } } } } dp_prev_aho = move(dp_next_aho); } int total_aho = 0; for (int tight = 0; tight < 2; ++tight) for (int sm = 0; sm < 3; ++sm) for (int ht = 0; ht < 2; ++ht) if (sm == 0 || ht) total_aho = (total_aho + dp_prev_aho[tight][sm][ht]) % MOD; // Compute aho_p vector>>> dp_prev_ahop(2, vector>>(3, vector>(2, vector(P, 0)))); dp_prev_ahop[1][0][0][0] = 1; for (int i = 0; i < n; ++i) { int d = digits[i]; vector>>> dp_next_ahop(2, vector>>(3, vector>(2, vector(P, 0)))); for (int tight = 0; tight < 2; ++tight) { for (int sm = 0; sm < 3; ++sm) { for (int ht = 0; ht < 2; ++ht) { for (int rp = 0; rp < P; ++rp) { if (dp_prev_ahop[tight][sm][ht][rp] == 0) continue; int max_digit = (tight) ? d : 9; for (int next_d = 0; next_d <= max_digit; ++next_d) { int new_tight = (tight && (next_d == max_digit)) ? 1 : 0; int new_sm = (sm + next_d) % 3; int new_ht = ht || (next_d == 3); int new_rp = (rp * 10 + next_d) % P; dp_next_ahop[new_tight][new_sm][new_ht][new_rp] = (dp_next_ahop[new_tight][new_sm][new_ht][new_rp] + dp_prev_ahop[tight][sm][ht][rp]) % MOD; } } } } } dp_prev_ahop = move(dp_next_ahop); } int total_ahop = 0; for (int tight = 0; tight < 2; ++tight) for (int sm = 0; sm < 3; ++sm) for (int ht = 0; ht < 2; ++ht) for (int rp = 0; rp < P; ++rp) if ((sm == 0 || ht) && rp == 0) total_ahop = (total_ahop + dp_prev_ahop[tight][sm][ht][rp]) % MOD; return {total_aho, total_ahop}; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); string A, B; int P; cin >> A >> B >> P; string A_minus_1 = decrement(A); DPResult resB = compute(B, P); DPResult resA = compute(A_minus_1, P); int total_aho = (resB.aho - resA.aho + MOD) % MOD; int total_ahop = (resB.aho_p - resA.aho_p + MOD) % MOD; int ans = (total_aho - total_ahop + MOD) % MOD; cout << ans << "\n"; return 0; }