#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <limits>
#include <stack>
#include <queue>
#include <map> 
using namespace std;

#define LL long long
#define MOD (1000000007)


//135
int main() {
	static char s[100010];
	scanf("%s", s);

	static LL dp[100010][13];
	memset(dp, 0, sizeof(dp));
	dp[0][0] = 1;

	LL len = strlen(s);

	LL mod_keta = 1;

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

		for (LL num = 0; num <= 9; num++) {
			if (s[len - i] != '?' && num != (s[len - i] - '0')) {
				continue;
			}

			LL mod13_keta = (mod_keta * num) % 13;

			for (LL num_prev = 0; num_prev <= 12; num_prev++) {

				LL mod13_result = (num_prev + mod13_keta) % 13;

				dp[i][mod13_result] += dp[i - 1][num_prev];
				dp[i][mod13_result] %= MOD;
			}
		}

		mod_keta = (mod_keta * 10) % 13;
	}

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

	return 0;
}

//134
/*
int main() {
	LL N;

	scanf("%lld", &N);

	vector<unsigned int> A(N + 1);

	for (LL i = 1; i <= N; i++) {
		scanf("%d", &A[i]);
	}

	vector<unsigned int> B(N + 1);

	vector<unsigned int> result;

	for (LL i = N; i >= 1; i--) {
		LL count = 0;

		LL num = i * 2;
		while (num <= N) {
			count += B[num];
			num += i;
		}

		if (count % 2 != A[i]) {
			B[i] = 1;
			result.push_back(i);
		}
	}

	printf("%d\n", (unsigned int)result.size());
	for (auto item : result) {
		printf("%d ", item);
	}
	printf("\n");

	return 0;
}
*/


//133
/*
int main() {
	LL N;

	scanf("%lld", &N);

	vector<LL> A(N);

	for (LL i = 0; i < N; i++) {
		scanf("%lld", &A[i]);
	}

	vector<LL> R(N);

	R[0] = 0;
	for (LL i = 0; i < N; i++) {
		if (i % 2 == 0) {
			R[0] += A[i];
		}
		else {
			R[0] -= A[i];
		}
	}

	R[N - 1] = 2 * A[N - 1] - R[0];
	for (LL i = N - 2; i > 0; i--) {
		R[i] = 2 * A[i] - R[i + 1];
	}

	for (int i = 0; i < N; i++) {
		printf("%lld ", R[i]);
	}
	printf("\n");

	return 0;
}
*/


//132
/*
// mod. m �ł� a �̋t�� a^{-1} ���v�Z����
LL modinv(LL a, LL m) {
	LL b = m, u = 1, v = 0;
	while (b) {
		LL t = a / b;
		a -= t * b; swap(a, b);
		u -= t * v; swap(u, v);
	}
	u %= m;
	if (u < 0) u += m;
	return u;
}

LL calcCombinationMOD(LL n, LL r, LL mod) {
	LL num = 1;
	for (LL i = 1; i <= r; i++) {
		num = num * (n - i + 1);
		num = num % mod;
		num = (num * modinv(i, mod)) % mod;
	}
	return num;
}

LL calcHomogeneousProductMOD(LL n, LL r, LL mod) {
	return calcCombinationMOD(n + r - 1, r, mod);
}

int main() {
	LL N, B;
	scanf("%lld %lld", &N, &B);

	LL R = N - B;

	for (LL i = 1; i <= B; i++) {
		LL lastB = B - i;
		LL lastR = R - (i - 1);

		if (lastR < 0) {
			printf("0\n");
			continue;
		}

		LL boxB = i;
		LL boxR = i + 1;

		LL patternB = calcHomogeneousProductMOD(boxB, lastB, MOD);
		LL patternR = calcHomogeneousProductMOD(boxR, lastR, MOD);
		LL result = (patternB * patternR) % MOD;

		printf("%lld\n", result);
	}
}
*/


//131
/*
struct LLPair {
	LL A, B;
};

int main() {
	LL N;

	scanf("%lld", &N);

	vector<LLPair> A(N);

	for (int i = 0; i < N; i++) {
		LL a, b;
		scanf("%lld %lld", &a, &b);

		A[i].A = a;
		A[i].B = b;
	}

	std::sort(A.begin(), A.end(), [](const LLPair &a, const LLPair &b) {
		return a.B < b.B;
	});

	LL time = 0;
	bool success = true;
	for (auto item : A) {
		time += item.A;
		if (time > item.B) {
			success = false;
		}
	}

	if (success) {
		printf("Yes\n");
	}
	else {
		printf("No\n");
	}

	return 0;
}
*/


//130
/*
int main() {
	LL N, K;

	scanf("%lld %lld", &N, &K);

	vector<LL> a(N);

	for (int i = 0; i < N; i++) {
		scanf("%lld", &a[i]);
	}

	LL result = 0;

	LL begin = 0, end = 0;
	LL total = a[0];

	while (true) {
		if (total >= K) {
			if (total >= K) {
				result++;
				result += N - end - 1;
			}

			//�[�����Ă���̂�begin��i�߂�
			if (begin == end) {
				begin++;
				end++;
				total = a[begin];
			}
			else {
				total -= a[begin];
				begin++;
			}
		}
		else {
			//�[�����Ă��Ȃ��̂�end��i�߂�
			end++;
			if (end >= N) {
				break;
			}
			else {
				total += a[end];
			}
		}
	}

	printf("%lld\n", result);

	return 0;
}
*/


//129
/*
int main() {
	LL H, W;

	scanf("%lld %lld", &H, &W);

	static int hor_label[2020][2020];
	static int var_label[2020][2020];

	static int hor_label_to_count[2020 * 2020];
	static int var_label_to_count[2020 * 2020];

	memset(hor_label, 0, sizeof(hor_label));
	memset(var_label, 0, sizeof(var_label));
	memset(hor_label_to_count, 0, sizeof(hor_label_to_count));
	memset(var_label_to_count, 0, sizeof(var_label_to_count));

	char s[2020];
	int hor_curr_label = 1;
	int var_curr_label = 1;
	for (int j = 0; j < H; j++) {
		scanf("%s", &s);
		
		for (int i = 0; i < W; i++) {
			if (s[i] == '.') {
				hor_label[j][i] = hor_curr_label;
				hor_label_to_count[hor_curr_label]++;

				if (j == 0) {
					var_label[j][i] = var_curr_label;
					var_label_to_count[var_curr_label]++;
					var_curr_label++;
				}
				else {
					int abobe_label = var_label[j - 1][i];
					if (abobe_label > 0) {
						var_label[j][i] = abobe_label;
						var_label_to_count[abobe_label]++;
					}
					else {
						var_label[j][i] = var_curr_label;
						var_label_to_count[var_curr_label]++;
						var_curr_label++;
					}
				}
			}
			else {
				hor_curr_label++;
			}
		}

		hor_curr_label++;
	}

	LL result = 0;

	for (int j = 0; j < H; j++) {
		for (int i = 0; i < W; i++) {
			if (hor_label[j][i] == 0) {
				continue;
			}

			LL count = hor_label_to_count[hor_label[j][i]] + var_label_to_count[var_label[j][i]] - 1;

			result = max(count, result);
		}
	}

	printf("%lld\n", result);

	return 0;
}
*/


//128
/*
int main() {
	LL N, K;
	scanf("%lld %lld", &N, &K);

	vector<LL> V(N);
	vector<LL> Lval(N + 1);
	Lval[0] = 0;
	for (int i = 0; i < N; i++) {
		scanf("%lld", &V[i]);
		Lval[i + 1] = Lval[i] + V[i];
	}

	vector<LL> Rval(N + 1);
	Rval[0] = 0;
	for (int i = 0; i < N; i++) {
		Rval[i + 1] = Rval[i] + V[N - i - 1];
	}

	vector<vector<vector<LL>>> Dq(N + 1, vector<vector<LL>>(N + 1, vector<LL>(0)));

	for (int i = 0; i <= N; i++) { //L
		for (int j = 0; j <= N - i; j++) { //R
			for (int l = 0; l < i; l++) {
				if (V[l] < 0) {
					Dq[i][j].push_back(V[l]);
				}
			}

			for (int r = 0; r < j; r++) {
				if (V[N - r - 1] < 0) {
					Dq[i][j].push_back(V[N - r - 1]);
				}
			}

			if (Dq[i][j].size() > 0) {
				std::sort(Dq[i][j].begin(), Dq[i][j].end());
			}
		}
	}

	LL result = 0;

	LL max_get = min(N, K);

	for (int l = 0; l <= max_get; l++) {
		for (int r = 0; r <= max_get - l; r++) {
			for (int d = 0; d <= K - l - r; d++) {
				LL value = Lval[l] + Rval[r];
				
				int dis = min(d, (int)Dq[l][r].size());
				for (int i = 0; i < dis; i++) {
					value -= Dq[l][r][i];
				}

				result = max(result, value);
			}
		}
	}

	printf("%lld\n", result);

	return 0;
}
*/


//127
/*
struct IntPair {
	LL B, C;
};

int main() {
	LL N, M;

	scanf("%lld %lld", &N, &M);

	vector<LL> A;

	for (int i = 0; i < N; i++) {
		LL val;
		scanf("%lld", &val);
		A.push_back(val);
	}
	
	vector<IntPair> P;

	for (int i = 0; i < M; i++) {
		LL val1, val2;
		scanf("%lld %lld", &val1, &val2);
		IntPair pair;
		pair.B = val1;
		pair.C = val2;
		P.push_back(pair);
	}

	std::sort(A.begin(), A.end());

	std::sort(P.begin(), P.end(), [](const IntPair &a, const IntPair &b) {
		return a.C > b.C;
	});

	LL indexA = 0;
	bool finish = false;
	for (auto item : P) {
		for (int i = 0; i < item.B; i++) {
			if (item.C > A[indexA]) {
				A[indexA] = item.C;
			}
			else {
				finish = true;
				break;
			}

			indexA++;

			if (indexA >= N) {
				finish = true;
				break;
			}
		}

		if (finish) {
			break;
		}
	}

	LL result = 0;
	for (auto item : A) {
		result += item;
	}

	printf("%lld\n", result);

	return 0;
}
*/

//126
/*
struct Node {
	unsigned int connect;
	unsigned int weight;
};

int main() {
	LL N;

	scanf("%lld", &N);

	static vector<Node> node[100010];
	static char color[100010];

	for (int i = 0; i < N - 1; i++) {
		unsigned int u, v, w;

		scanf("%d %d %d", &u, &v, &w);

		Node n1;
		n1.connect = v;
		n1.weight = w;
		node[u].push_back(n1);

		Node n2;
		n2.connect = u;
		n2.weight = w;
		node[v].push_back(n2);
	}

	for (int i = 0; i <= N; i++) {
		color[i] = -1;
	}

	std::queue<unsigned int> q;

	color[1] = 0;
	q.push(1);

	//���D��T��
	while (q.size() > 0) {
		unsigned int index = q.front();
		q.pop();

		char c = color[index];

		for (auto item : node[index]) {
			if (color[item.connect] < 0) {
				//�܂��ʂ��Ă��Ȃ��m�[�h
				color[item.connect] = item.weight % 2 == 0 ? c : 1 - c;
				q.push(item.connect);
			}
		}
	}

	for (int i = 1; i <= N; i++) {
		printf("%d\n", color[i]);
	}

	return 0;
}
*/

Measured memory_bytes: 10496