stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include <iostream>

#include <cstring>

# define mod 1000000007

using namespace std;

typedef long long ll;

ll dp[100009][13];

int main(){

	string s;

	cin>>s;

	memset(dp,0,sizeof(dp));

	if(s[0]=='?')

		for(int i=0;i<10;i++)

			dp[0][i]=1;

	else

		dp[0][s[0]-'0']=1;

		int len=s.length();

	for(int i=1;i<len;i++)

	{

		if(s[i]=='?')

		{

			for(int j=0;j<13;j++)

				for(int k=0;k<10;k++)

				{

					dp[i][(j*10+k)%13]+=dp[i-1][j];

					dp[i][(j*10+k)%13]%=mod;

				}

		}

		else

		{

			for(int j=0;j<13;j++)

			{

				dp[i][(s[i]-'0'+j*10)%13]+=dp[i-1][j];

				dp[i][(s[i]-'0'+j*10)%13]%=mod;

			}

		}

	}

		 cout<<dp[len-1][5]<<endl;

	return 0;

} 

// Faster C++ solution for the same problem (measured speedup: 11.896301494135553x):
#include <bits/stdc++.h>

#define maxn 100005

using namespace std;

typedef long long ll;

char str[maxn];

ll dp[maxn][20];

const int mod=1e9+7;

int main()

{

    scanf("%s",str+1);

    int len=strlen(str+1);

    dp[0][0]=1;

    for(int i=1;i<=len;i++){

        if(str[i]!='?'){

            for(int j=0;j<13;j++){

                dp[i][(j*10+str[i]-'0')%13]=(dp[i][(j*10+str[i]-'0')%13]+dp[i-1][j])%mod;

            }

        }

        else{

            for(int j=0;j<=9;j++){

                for(int k=0;k<13;k++){

                    dp[i][(k*10+j)%13]=(dp[i][(k*10+j)%13]+dp[i-1][k])%mod;

                }

            }

        }

    }

    printf("%lld\n",dp[len][5]);

    return 0;

}
// Slower C++ solution:
#include <iostream>

#include <cstring>

# define mod 1000000007

using namespace std;

typedef long long ll;

ll dp[100009][13];

int main(){

	string s;

	cin>>s;

	memset(dp,0,sizeof(dp));

	if(s[0]=='?')

		for(int i=0;i<10;i++)

			dp[0][i]=1;

	else

		dp[0][s[0]-'0']=1;

		int len=s.length();

	for(int i=1;i<len;i++)

	{

		if(s[i]=='?')

		{

			for(int j=0;j<13;j++)

				for(int k=0;k<10;k++)

				{

					dp[i][(j*10+k)%13]+=dp[i-1][j];

					dp[i][(j*10+k)%13]%=mod;

				}

		}

		else

		{

			for(int j=0;j<13;j++)

			{

				dp[i][(s[i]-'0'+j*10)%13]+=dp[i-1][j];

				dp[i][(s[i]-'0'+j*10)%13]%=mod;

			}

		}

	}

		 cout<<dp[len-1][5]<<endl;

	return 0;

} 

// Faster C++ solution for the same problem (measured speedup: 56.65857857741935x):
#include <cstdio>

#include <cstring>

#include <algorithm>

using namespace std;

const int maxd = 1e5+10;

const int mod = 1e9+7;

char s[maxd];

int dp[maxd][20];

int main()

{

	// freopen("a.in","r",stdin);

	// freopen("k.out","w",stdout);

	scanf("%s",s+1);

	dp[0][0] = 1;

	for(int i=1;s[i];i++)

	{

		if(s[i] != '?')

		{

			int k = s[i] - '0';

			for(int j=0;j<13;j++)

				dp[i][(j*10+k)%13] = (1ll * dp[i][(j*10+k)%13] + dp[i-1][j])%mod;

		}

		else 

		{

			for(int k=0;k<10;k++)

				for(int j=0;j<13;j++)

					dp[i][(j*10+k)%13] = (1ll * dp[i][(k+j*10)%13] + dp[i-1][j])%mod;

		}

	}

	printf("%d",dp[strlen(s+1)][5]);

	return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>

#define maxn 100005

using namespace std;

typedef long long ll;

char str[maxn];

ll dp[maxn][20];

const int mod=1e9+7;

int main()

{

    scanf("%s",str+1);

    int len=strlen(str+1);

    dp[0][0]=1;

    for(int i=1;i<=len;i++){

        if(str[i]!='?'){

            for(int j=0;j<13;j++){

                dp[i][(j*10+str[i]-'0')%13]=(dp[i][(j*10+str[i]-'0')%13]+dp[i-1][j])%mod;

            }

        }

        else{

            for(int j=0;j<=9;j++){

                for(int k=0;k<13;k++){

                    dp[i][(k*10+j)%13]=(dp[i][(k*10+j)%13]+dp[i-1][k])%mod;

                }

            }

        }

    }

    printf("%lld\n",dp[len][5]);

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 4.762705333699721x):
#include <cstdio>

#include <cstring>

#include <algorithm>

using namespace std;

const int maxd = 1e5+10;

const int mod = 1e9+7;

char s[maxd];

int dp[maxd][20];

int main()

{

	// freopen("a.in","r",stdin);

	// freopen("k.out","w",stdout);

	scanf("%s",s+1);

	dp[0][0] = 1;

	for(int i=1;s[i];i++)

	{

		if(s[i] != '?')

		{

			int k = s[i] - '0';

			for(int j=0;j<13;j++)

				dp[i][(j*10+k)%13] = (1ll * dp[i][(j*10+k)%13] + dp[i-1][j])%mod;

		}

		else 

		{

			for(int k=0;k<10;k++)

				for(int j=0;j<13;j++)

					dp[i][(j*10+k)%13] = (1ll * dp[i][(k+j*10)%13] + dp[i-1][j])%mod;

		}

	}

	printf("%d",dp[strlen(s+1)][5]);

	return 0;

}
// Slower C++ solution:
#include <iostream>

#include <cstring>

# define mod 1000000007

using namespace std;

typedef long long ll;

ll dp[100009][13];

int main(){

	string s;

	cin>>s;

	memset(dp,0,sizeof(dp));

	if(s[0]=='?')

		for(int i=0;i<10;i++)

			dp[0][i]=1;

	else

		dp[0][s[0]-'0']=1;

		int len=s.length();

	for(int i=1;i<len;i++)

	{

		if(s[i]=='?')

		{

			for(int j=0;j<13;j++)

				for(int k=0;k<10;k++)

				{

					dp[i][(j*10+k)%13]+=dp[i-1][j];

					dp[i][(j*10+k)%13]%=mod;

				}

		}

		else

		{

			for(int j=0;j<13;j++)

			{

				dp[i][(s[i]-'0'+j*10)%13]+=dp[i-1][j];

				dp[i][(s[i]-'0'+j*10)%13]%=mod;

			}

		}

	}

		 cout<<dp[len-1][5]<<endl;

	return 0;

} 

// Faster C++ solution for the same problem (measured speedup: 11.95105844362714x):
#include <bits/stdc++.h>

using namespace std;

const int mod = 1e9 + 7;

char s[100005];

int dp[100005][13]; //dp[i][j]表示到第i个字符为止，除以13余j(j表示的是到i-1为止模13余j)有多少种情况

// 难在找出状态转移方程

int main()

{

   // cout<<mod<<'\n';

    

    scanf("%s", s + 1);

    int n = strlen(s + 1);

    dp[0][0] = 1;

    for (int i = 1; i <= n; i++)

    {

        if (s[i] != '?')

        {

            s[i] -= '0';

            for (int j = 0; j < 13; j++)

            {

                dp[i][(j * 10 + s[i]) % 13] = (dp[i][(j * 10 + s[i]) % 13] + dp[i - 1][j]) % mod;

            }

        }

        else

        {

            for (int k = 0; k < 10; k++)

            {

                for (int j = 0; j < 13; j++)

                {

                    dp[i][(j * 10 + k) % 13] = (dp[i][(j * 10 + k) % 13] + dp[i - 1][j]) % mod;

                }

            }

        }

    }

    printf("%d\n", dp[n][5]);

}
// Slower C++ solution:
#include<bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>

#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;

using namespace std;

#define Khela ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

#define ll long long int

#define llu long long unsigned int

#define pf printf

#define sf scanf

#define f first

#define s second

#define pb push_back

#define mk make_pair

#define pii pair<int ,int>

#define PII pair<ll ,ll>

 

int dx8[] = {0, 0, 1, 1, 1, -1, -1, -1};

int dy8[] = {1,-1, 1, -1, 0, 0, -1, 1};

int dx4[] = {0, 0, 1, -1};

int dy4[] = {1, -1, 0, 0};

 

typedef tree<pair<int,int>,null_type,less<pair<int,int>>,rb_tree_tag,tree_order_statistics_node_update>ordered_set;

int Set(int N,int pos){return N=N | (1<<pos);}

int reset(int N,int pos){return N= N & ~(1<<pos);}

bool check(int N,int pos){return (bool)(N & (1<<pos));}

const int max=1e9+100;

const ll  MAX=1e18+500;

const int sz=1e5+100;

const ll mod=1e9+7;

int mark[sz];

ll dp[sz][14];

ll n;

string str;

ll cholo(ll id,ll sum)

{

    if(id>=n){

        if(sum%13==5) return 1;

        else return 0;

    }



    ll &ret=dp[id][sum];

    if(~ret) return ret;

    ll tot=0;

    if(str[id] != '?') ret=cholo(id+1,(sum*10+(str[id]-'0'))%13);

    else{

        for(ll i=0;i<=9;i++) tot=(tot+cholo(id+1,(sum*10+i)%13))%mod;

        ret=tot;

    }



    return ret;

    

    

}

int main()

{

    Khela

    ll a,b,c,i,j,k,q,p,x,y,ct,ct1,m,l,r,x1,y1,mn,h,sum1,in,z,mid,mx;

    char ch;

    double d;

    //string str1;

    bool bl,bl1;

    int t,cs=1;

    while(cin>>str)

    {

        memset(dp,-1,sizeof dp);

        n=str.length();

        ll ans=cholo(0,0);

        cout<<ans<<endl;

      

        

    }











}

// Faster C++ solution for the same problem (measured speedup: 12.830630495274962x):
#include <bits/stdc++.h>

using namespace std;

const int mod = 1e9 + 7;

char s[100005];

int dp[100005][13]; //dp[i][j]表示到第i个字符为止，除以13余j(j表示的是到i-1为止模13余j)有多少种情况

// 难在找出状态转移方程

int main()

{

   // cout<<mod<<'\n';

    

    scanf("%s", s + 1);

    int n = strlen(s + 1);

    dp[0][0] = 1;

    for (int i = 1; i <= n; i++)

    {

        if (s[i] != '?')

        {

            s[i] -= '0';

            for (int j = 0; j < 13; j++)

            {

                dp[i][(j * 10 + s[i]) % 13] = (dp[i][(j * 10 + s[i]) % 13] + dp[i - 1][j]) % mod;

            }

        }

        else

        {

            for (int k = 0; k < 10; k++)

            {

                for (int j = 0; j < 13; j++)

                {

                    dp[i][(j * 10 + k) % 13] = (dp[i][(j * 10 + k) % 13] + dp[i - 1][j]) % mod;

                }

            }

        }

    }

    printf("%d\n", dp[n][5]);

}
// Slower C++ solution:
#include <iostream>

#include <cstring>

# define mod 1000000007

using namespace std;

typedef long long ll;

ll dp[100009][13];

int main(){

	string s;

	cin>>s;

	memset(dp,0,sizeof(dp));

	if(s[0]=='?')

		for(int i=0;i<10;i++)

			dp[0][i]=1;

	else

		dp[0][s[0]-'0']=1;

		int len=s.length();

	for(int i=1;i<len;i++)

	{

		if(s[i]=='?')

		{

			for(int j=0;j<13;j++)

				for(int k=0;k<10;k++)

				{

					dp[i][(j*10+k)%13]+=dp[i-1][j];

					dp[i][(j*10+k)%13]%=mod;

				}

		}

		else

		{

			for(int j=0;j<13;j++)

			{

				dp[i][(s[i]-'0'+j*10)%13]+=dp[i-1][j];

				dp[i][(s[i]-'0'+j*10)%13]%=mod;

			}

		}

	}

		 cout<<dp[len-1][5]<<endl;

	return 0;

} 

// Faster C++ solution for the same problem (measured speedup: 1.654849366445626x):
/**

*   @Author : MeGA

*   @InitTime :01/25/20 11:11:36

*   @Idea : 

*

*

*

*

*

*

*

**/

#include <bits/stdc++.h>

using namespace std;

string s;

int n;



const int MOD=1e9+7;

int dp[(int)1e5+7][15];

int solve(int idx,int rem){

    if(idx==n){

       return rem==5?1:0;

    }

    int &ret=dp[idx][rem];

    if(ret!=-1){

    	return  ret;

    }

    ret=0;

    if(s[idx] != '?')

    return ret=solve(idx+1,(rem*10+(s[idx]-'0'))%13);

    for(int i=0;i<=9;i++){

       ret=(1ll*ret+1ll*solve(idx+1,(rem*10+i)%13))%MOD;

    }

    return ret;

}

int main(){

#ifndef ONLINE_JUDGE

  // freopen("in","r",stdin);

  // freopen("out","w",stdout);

#endif

     cin>>s;

     n=s.size();

     memset(dp,-1,sizeof(dp));

     printf("%d",solve(0,0));





}
// Slower C++ solution:
#include<bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>

#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;

using namespace std;

#define Khela ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

#define ll long long int

#define llu long long unsigned int

#define pf printf

#define sf scanf

#define f first

#define s second

#define pb push_back

#define mk make_pair

#define pii pair<int ,int>

#define PII pair<ll ,ll>

 

int dx8[] = {0, 0, 1, 1, 1, -1, -1, -1};

int dy8[] = {1,-1, 1, -1, 0, 0, -1, 1};

int dx4[] = {0, 0, 1, -1};

int dy4[] = {1, -1, 0, 0};

 

typedef tree<pair<int,int>,null_type,less<pair<int,int>>,rb_tree_tag,tree_order_statistics_node_update>ordered_set;

int Set(int N,int pos){return N=N | (1<<pos);}

int reset(int N,int pos){return N= N & ~(1<<pos);}

bool check(int N,int pos){return (bool)(N & (1<<pos));}

const int max=1e9+100;

const ll  MAX=1e18+500;

const int sz=1e5+100;

const ll mod=1e9+7;

int mark[sz];

ll dp[sz][14];

ll n;

string str;

ll cholo(ll id,ll sum)

{

    if(id>=n){

        if(sum%13==5) return 1;

        else return 0;

    }



    ll &ret=dp[id][sum];

    if(~ret) return ret;

    ll tot=0;

    if(str[id] != '?') ret=cholo(id+1,(sum*10+(str[id]-'0'))%13);

    else{

        for(ll i=0;i<=9;i++) tot=(tot+cholo(id+1,(sum*10+i)%13))%mod;

        ret=tot;

    }



    return ret;

    

    

}

int main()

{

    Khela

    ll a,b,c,i,j,k,q,p,x,y,ct,ct1,m,l,r,x1,y1,mn,h,sum1,in,z,mid,mx;

    char ch;

    double d;

    //string str1;

    bool bl,bl1;

    int t,cs=1;

    while(cin>>str)

    {

        memset(dp,-1,sizeof dp);

        n=str.length();

        ll ans=cholo(0,0);

        cout<<ans<<endl;

      

        

    }











}

// Faster C++ solution for the same problem (measured speedup: 1.7766427004234084x):
/**

*   @Author : MeGA

*   @InitTime :01/25/20 11:11:36

*   @Idea : 

*

*

*

*

*

*

*

**/

#include <bits/stdc++.h>

using namespace std;

string s;

int n;



const int MOD=1e9+7;

int dp[(int)1e5+7][15];

int solve(int idx,int rem){

    if(idx==n){

       return rem==5?1:0;

    }

    int &ret=dp[idx][rem];

    if(ret!=-1){

    	return  ret;

    }

    ret=0;

    if(s[idx] != '?')

    return ret=solve(idx+1,(rem*10+(s[idx]-'0'))%13);

    for(int i=0;i<=9;i++){

       ret=(1ll*ret+1ll*solve(idx+1,(rem*10+i)%13))%MOD;

    }

    return ret;

}

int main(){

#ifndef ONLINE_JUDGE

  // freopen("in","r",stdin);

  // freopen("out","w",stdout);

#endif

     cin>>s;

     n=s.size();

     memset(dp,-1,sizeof(dp));

     printf("%d",solve(0,0));





}
// Slower C++ solution:
#include <bits/stdc++.h>

#define all(a) a.begin(), a.end()

#define rall(a) a.rbegin(), a.rend()

#define rep(i, s, N) for(ll i{s}; i < N; i++)

#define rem(i, N, s) for(ll i{N}; i > s; i--)

using namespace std;using ll = long long int;using ld = long double;using P = pair<ll,ll>;const int MOD = (int)1e9+7;const string rt = "\n";const string sp = " ";/* 最大公約数 */template<typename T> T gcd(T a, T b){return b != 0 ? gcd(b, a % b) : a;}/* UnionFind */template<typename T> struct UnionFind{vector<T> par;UnionFind(T n) : par(n, -1){}void init(T n){par.assign(n, -1);}T root(T x){if (par[x] < 0) return x;else return par[x] = root(par[x]);}bool issame(T x, T y){return root(x) == root(y);}bool merge(T x, T y){x = root(x); y = root(y);if(x == y) return false;if(par[x] > par[y]) swap(x, y);par[x] += par[y];par[y] = x;return true;}int size(int x) {return -par[root(x)];}};/* コンビネーション */template<typename T> ll combpm(T N_, T C_) {const int NUM_=400001;static ll fact[NUM_+1],factr[NUM_+1],inv[NUM_+1];if (fact[0]==0) {inv[1]=fact[0]=factr[0]=1;for (int i=2;i<=NUM_;++i) inv[i] = inv[MOD % i] * (MOD - MOD / i) % MOD;for (int i=1;i<=NUM_;++i) fact[i]=fact[i-1]*i%MOD, factr[i]=factr[i-1]*inv[i]%MOD;}if(C_<0 || C_>N_) return 0;return factr[C_]*fact[N_]%MOD*factr[N_-C_]%MOD;}/* 多次元ベクター */template<class T>vector<T> mvec(size_t a){return vector<T>(a);}template<class T, class... Ts>auto mvec(size_t a, Ts... ts){return vector<decltype(mvec<T>(ts...))>(a, mvec<T>(ts...));}/* テスト関数 */void test(ll n){cout << "test" << n << endl;}/* 小数点以下 */void fixsp(ll n){cout << fixed << setprecision(n);}void defsp(ll n){cout << defaultfloat << setprecision(n);}/* 重み付きUnionFind */struct WUnionFind {vector<int> par;vector<int> rank;WUnionFind(int n = 1) {init(n);}void init(int n = 1) {par.resize(n); rank.resize(n);for (int i = 0; i < n; ++i) par[i] = i, rank[i] = 0;}int root(int x) {if (par[x] == x) {return x;}else {int r = root(par[x]);return par[x] = r;}}bool issame(int x, int y) {return root(x) == root(y);}bool merge(int x, int y) {x = root(x); y = root(y);if (x == y) return false;if (rank[x] < rank[y]) swap(x, y);if (rank[x] == rank[y]) ++rank[x];par[y] = x;return true;}};/* IO高速化 */void fastio(){ios::sync_with_stdio(false);cin.tie(NULL);}

/* ここからコード開始 */



int main(){

  fastio;

  string S;

  cin >> S;

  ll N = S.size(); reverse(all(S));

  auto DP = mvec<ll>(N+1,13); DP[0][0] = 1;

  auto d13 = [](ll n) -> ll{

    return (13 + n % 13)%13;

  };

  auto deal = [&](ll i, ll j, ll l) -> void{

    ll k{};

    k = l + d13(j*pow(10, i%3)) * pow(-1, i/3);

    DP[i+1][d13(k)] += DP[i][l]%MOD;

  };

  rep(i, 0, N) rep(l, 0, 13){

    if(S[i] == '?') rep(j, 0, 10) deal(i, j, l);

    else deal (i, S[i] - '0', l);

  }

  cout << DP[N][5]%MOD << rt;

}

// Faster C++ solution for the same problem (measured speedup: 1.174000340930719x):
#include<bits/stdc++.h>

#define rep(i,j) for(int i{};i<j;i++)

using namespace std;int d[100001][13];void f(int i, int j, int k){(d[i+1][k%13]+=d[i][j])%=1000000007;}main(){string s;cin>>s;d[0][0]=1;rep(i,s.size())rep(j,13){if(s[i]=='?')rep(k,10)f(i,j,j*10+k);else f(i,j,j*10+s[i]-'0');}cout<<d[s.size()][5];}
// Slower C++ solution:
#include <bits/stdc++.h>

#define all(a) a.begin(), a.end()

#define rep(i, s, N) for(ll i{s}; i < N; i++)

using namespace std;using ll = long long int;const int MOD = (int)1e9+7;template<class T>vector<T> mvec(size_t a){return vector<T>(a);}template<class T, class... Ts>auto mvec(size_t a, Ts... ts){return vector<decltype(mvec<T>(ts...))>(a, mvec<T>(ts...));}



int main(){

  string S;

  cin >> S;

  ll N = S.size(); reverse(all(S));

  auto DP = mvec<ll>(N+1,13); DP[0][0] = 1;

  auto d13 = [](ll n) -> ll{

    return (13 + n % 13)%13;

  };

  auto deal = [&](ll i, ll j, ll l) -> void{

    ll k{};

    k = l + d13(j*pow(10, i%3)) * pow(-1, i/3);

    DP[i+1][d13(k)] += DP[i][l]%MOD;

  };

  rep(i, 0, N) rep(l, 0, 13){

    if(S[i] == '?') rep(j, 0, 10) deal(i, j, l);

    else deal (i, S[i] - '0', l);

  }

  cout << DP[N][5]%MOD << "\n";

}

// Faster C++ solution for the same problem (measured speedup: 1.1674888314534109x):
#include<bits/stdc++.h>

#define rep(i,j) for(int i{};i<j;i++)

using namespace std;int d[100001][13];void f(int i, int j, int k){(d[i+1][k%13]+=d[i][j])%=1000000007;}main(){string s;cin>>s;d[0][0]=1;rep(i,s.size())rep(j,13){if(s[i]=='?')rep(k,10)f(i,j,j*10+k);else f(i,j,j*10+s[i]-'0');}cout<<d[s.size()][5];}
// Slower C++ solution:
#include <bits/stdc++.h>

#define rep(i, N) for(int i{};i<N;i++)

using namespace std;

int M = 1e9+7;

int p[100001][13];

string S;

int d(int n){

  return (13 + n%13)%13;

}

void f(int i, int j, int l){

  int k{};

  k = l + d(j*pow(10, i%3)) * pow(-1, i/3);

  (p[i+1][d(k)] += p[i][l]) %= M;

}

int main(){

  cin >> S;

  reverse(S.begin(), S.end());

  p[0][0] = 1;

  rep(i, S.size()) rep(l, 13){

    if(S[i] == '?') rep(j, 10) f(i, j, l);

    else f(i, S[i] - '0', l);

  }

  cout<<p[S.size()][5]<<"\n";

}

// Faster C++ solution for the same problem (measured speedup: 1.146964566367148x):
#include<bits/stdc++.h>

#define rep(i,j) for(int i{};i<j;i++)

using namespace std;int d[100001][13];void f(int i, int j, int k){(d[i+1][k%13]+=d[i][j])%=1000000007;}main(){string s;cin>>s;d[0][0]=1;rep(i,s.size())rep(j,13){if(s[i]=='?')rep(k,10)f(i,j,j*10+k);else f(i,j,j*10+s[i]-'0');}cout<<d[s.size()][5];}
// Slower C++ solution:
#include <bits/stdc++.h>

#define all(a) a.begin(), a.end()

#define rep(i, s, N) for(ll i{s}; i < N; i++)

using namespace std;using ll = long long int;const int MOD = (int)1e9+7;template<class T>vector<T> mvec(size_t a){return vector<T>(a);}template<class T, class... Ts>auto mvec(size_t a, Ts... ts){return vector<decltype(mvec<T>(ts...))>(a, mvec<T>(ts...));}



int main(){

  string S;

  cin >> S;

  ll N = S.size(); reverse(all(S));

  auto DP = mvec<ll>(N+1,13); DP[0][0] = 1;

  auto d13 = [](ll n) -> ll{

    return (13 + n % 13)%13;

  };

  auto deal = [&](ll i, ll j, ll l) -> void{

    ll k{};

    k = l + d13(j*pow(10, i%3)) * pow(-1, i/3);

    DP[i+1][d13(k)] += DP[i][l]%MOD;

  };

  rep(i, 0, N) rep(l, 0, 13){

    if(S[i] == '?') rep(j, 0, 10) deal(i, j, l);

    else deal (i, S[i] - '0', l);

  }

  cout << DP[N][5]%MOD << "\n";

}

// Faster C++ solution for the same problem (measured speedup: 1.1522116624254541x):
#include <bits/stdc++.h>

#define rep(i, N) for(int i{};i<N;i++)

using namespace std;

int M = 1e9+7;

int p[100001][13];

string S;

int d(int n){

  return (13 + n%13)%13;

}

void f(int &i, int j, int &l){

  int k{};

  k = l + d(j*(i%3==0?1:i%3==1?10:100)) * (1-i/3%2*2);

  (p[i+1][d(k)] += p[i][l]) %= M;

}

int main(){

  cin >> S;

  reverse(S.begin(), S.end());

  p[0][0] = 1;

  rep(i, S.size()) rep(l, 13){

    if(S[i] == '?') rep(j, 10) f(i, j, l);

    else f(i, S[i] - '0', l);

  }

  cout<<p[S.size()][5]<<"\n";

}
// Slower C++ solution:
#include <bits/stdc++.h>

#define rep(i, N) for(int i{};i<N;i++)

using namespace std;

int M = 1e9+7;

int p[100001][13];

string S;

int d(int n){

  return (13 + n%13)%13;

}

void f(int i, int j, int l){

  int k{};

  k = l + d(j*pow(10, i%3)) * pow(-1, i/3);

  (p[i+1][d(k)] += p[i][l]) %= M;

}

int main(){

  cin >> S;

  reverse(S.begin(), S.end());

  p[0][0] = 1;

  rep(i, S.size()) rep(l, 13){

    if(S[i] == '?') rep(j, 10) f(i, j, l);

    else f(i, S[i] - '0', l);

  }

  cout<<p[S.size()][5]<<"\n";

}

// Faster C++ solution for the same problem (measured speedup: 1.1319559675031619x):
#include <bits/stdc++.h>

#define rep(i, N) for(int i{};i<N;i++)

using namespace std;

int M = 1e9+7;

int p[100001][13];

string S;

int d(int n){

  return (13 + n%13)%13;

}

void f(int &i, int j, int &l){

  int k{};

  k = l + d(j*(i%3==0?1:i%3==1?10:100)) * (1-i/3%2*2);

  (p[i+1][d(k)] += p[i][l]) %= M;

}

int main(){

  cin >> S;

  reverse(S.begin(), S.end());

  p[0][0] = 1;

  rep(i, S.size()) rep(l, 13){

    if(S[i] == '?') rep(j, 10) f(i, j, l);

    else f(i, S[i] - '0', l);

  }

  cout<<p[S.size()][5]<<"\n";

}
// Slower C++ solution:
#include <bits/stdc++.h>

#define rep(i, N) for(int i{};i<N;i++)

using namespace std;

int M = 1e9+7;

int p[100001][13];

string S;

int d(int n){

  return (13 + n%13)%13;

}

void f(int &i, int j, int &l){

  int k{};

  k = l + d(j*pow(10, i%3)) * pow(-1, i/3);

  (p[i+1][d(k)] += p[i][l]) %= M;

}

int main(){

  cin >> S;

  reverse(S.begin(), S.end());

  p[0][0] = 1;

  rep(i, S.size()) rep(l, 13){

    if(S[i] == '?') rep(j, 10) f(i, j, l);

    else f(i, S[i] - '0', l);

  }

  cout<<p[S.size()][5]<<"\n";

}


// Faster C++ solution for the same problem (measured speedup: 1.1553733351041509x):
#include <bits/stdc++.h>

#define rep(i, N) for(int i{};i<N;i++)

using namespace std;

int M = 1e9+7;

int p[100001][13];

string S;

int d(int n){

  return (13 + n%13)%13;

}

void f(int &i, int j, int &l){

  int k{};

  k = l + d(j*(i%3==0?1:i%3==1?10:100)) * (1-i/3%2*2);

  (p[i+1][d(k)] += p[i][l]) %= M;

}

int main(){

  cin >> S;

  reverse(S.begin(), S.end());

  p[0][0] = 1;

  rep(i, S.size()) rep(l, 13){

    if(S[i] == '?') rep(j, 10) f(i, j, l);

    else f(i, S[i] - '0', l);

  }

  cout<<p[S.size()][5]<<"\n";

}