#include #define REP(x,y,z) for(int x=y;x<=z;x++) #define FORD(x,y,z) for(int x=y;x>=z;x--) #define MSET(x,y) memset(x,y,sizeof(x)) #define FOR(x,y) for(__typeof(y.begin()) x=y.begin();x!=y.end();x++) #define F first #define S second #define MP make_pair #define PB push_back #define SZ size() #define M 200005 #define MOD 1000000007 void RI(){} template void RI( int& head, T&... tail ) { scanf("%d",&head); RI(tail...); } using namespace std; typedef long long LL; int p; char a[M],b[M]; LL dp[M][2][2][3];//pos, same, has3, %3 void add(LL &x,LL y) { x += y; if(x>=MOD) x%=MOD; if(x<0) x = (x%MOD)+MOD; } bool has3(int x) { while(x) { if(x%10==3) return 1; x /= 10; } return false; } int solve2(char in[],int same) { int n,re=0; sscanf(in, "%d", &n); if(!same) n--; REP(i,0,n) if(i%3==0||has3(i)) if(i%p!=0) re++; return re; } LL solve(char in[],int same) { int n=strlen(in); if(n<=6) { return solve2(in,same); } int ni,nj,nk,nl; LL re=0; MSET(dp,0); REP(i,0,n-1) in[i]-='0'; REP(i,0,in[0]-1) dp[0][0][i==3][i%3]++; dp[0][1][in[0]==3][in[0]%3]++; REP(i,0,n-2)REP(j,0,1)REP(k,0,1)REP(l,0,2) if(dp[i][j][k][l]) { REP(num,0,9) { if(j==1 && num>in[i+1]) continue; ni = i+1; nj = (j==1 && num==in[i+1]); nk = k; if(num==3) nk=1; nl = (l+num)%3; add(dp[ni][nj][nk][nl], dp[i][j][k][l]); } } REP(j,0,same) add(re, dp[n-1][j][0][0]); REP(j,0,same)REP(l,0,2) add(re, dp[n-1][j][1][l]); ///// int end=n-4; if(p==80) end=n-5; if(p==800)end=n-6; int mult=1; if(p==80) mult=10; if(p==800)mult=100; int tail=0, tail2; REP(i,end+1,n-1) tail=tail*10+in[i]; REP(j,0,1)REP(k,0,1)REP(l,0,2)for(int num=0; num<1000; num+=8) { //bigger tail2 = num*mult; if(same && j && tail2>tail) continue; if(!same && j && tail2>=tail) continue; //no 3 if(k==0 && (l+num)%3!=0 && !has3(num)) continue; add(re, -dp[end][j][k][l]); } return re; } int main() { LL ans; while(~scanf("%s%s%d",a,b,&p)) { ans = solve(b,1)-solve(a,0); ans = ((ans%MOD)+MOD)%MOD; printf("%lld\n",ans); } return 0; }