Problem:
Score : 400 points

Problem Statement

Given is a string S. Each character in S is either a digit (0, ..., 9) or ?.

Among the integers obtained by replacing each occurrence of ? with a digit, how many have a remainder of 5 when divided by 13? An integer may begin with 0.

Since the answer can be enormous, print the count modulo 10^9+7.

Constraints

S is a string consisting of digits (0, ..., 9) and ?.

1 \leq |S| \leq 10^5

Input

Input is given from Standard Input in the following format:

S

Output

Print the number of integers satisfying the condition, modulo 10^9+7.

Sample Input 1

??2??5

Sample Output 1

768

For example, 482305, 002865, and 972665 satisfy the condition.

Sample Input 2

?44

Sample Output 2

1

Only 044 satisfies the condition.

Sample Input 3

7?4

Sample Output 3

0

We may not be able to produce an integer satisfying the condition.

Sample Input 4

?6?42???8??2??06243????9??3???7258??5??7???????774????4?1??17???9?5?70???76???

Sample Output 4

153716888

Solution in C# (Mono 4.6.2.0) (judge verdict: Runtime Error)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AtCorder
{
	public class Program
	{
		const int MOD = 1000000007;
		static void Main(string[] args)
		{
			Scanner cin = new Scanner();
			string s = cin.Next();
			List<int[]> d = new List<int[]>();
			for (int i = 0; i < 10; i++) {
				int[] dd = new int[6];
				dd[0] = (i * 1) % 13;
				dd[1] = (i * 10) % 13;
				dd[2] = (i * 100) % 13;
				dd[3] = (i * 1000) % 13;
				dd[4] = (i * 10000) % 13;
				dd[5] = (i * 100000) % 13;
				d.Add(dd);
			}

			long ans = 0;
			var ss = s.Reverse().ToArray();
			int l = s.Length;

			int b = 0;
			List<int> hatenas = new List<int>();
			for (int i = 0; i < l; i++) {
				if (ss[i] == '?') {
					hatenas.Add(i);
				} else {
					int j = ss[i] - '0';
					b = (b + d[j][i % 6]) % 13;
				}
			}

			int[,] count = new int[hatenas.Count, 13];
			for (int i = 0; i < hatenas.Count; i++) {
				int c = i % 6;
				for(int j = 0; j < 10; j++) {
					if (i == 0) {
						count[i, d[j][c]] = 1;
					} else {
						int dd = d[j][c];
						for (int k = 0; k < 10; k++) {
							int jj = (k + dd) % 13;
							count[i, jj] = (count[i, jj] + count[i - 1, k]) % MOD;
						}
					}
				}
			}

			int target = 5 - b;
			if (target < 0) {
				target += 13;
			}

			ans = count[hatenas.Count - 1, target];

			Console.WriteLine(ans);
		}
	}

	public class Scanner
	{
		private readonly char[] delimiter_ = new char[] { ' ' };
		private string[] buf_;
		private int index_;
		
		public Scanner()
		{
			buf_ = new string[0];
			index_ = 0;
		}

		public string Next()
		{
			if (index_ < buf_.Length) {
				return buf_[index_++];
			}

			string st = Console.ReadLine();
			while (st == "") {
				st = Console.ReadLine();
			}

			buf_ = st.Split(delimiter_, StringSplitOptions.RemoveEmptyEntries);
			if (buf_.Length == 0) {
				return Next();
			}

			index_ = 0;
			return buf_[index_++];
		}

		public int Int()
		{
			return int.Parse(Next());
		}
		public int[] ArrayInt(int N, int add = 0)
		{
			int[] Array = new int[N];
			for (int i = 0; i < N; i++) {
				Array[i] = Int() + add;
			}
			return Array;
		}

		public long Long()
		{
			return long.Parse(Next());
		}

		public long[] ArrayLong(int N, long add = 0)
		{
			long[] Array = new long[N];
			for (int i = 0; i < N; i++) {
				Array[i] = Long() + add;
			}
			return Array;
		}

		public double Double()
		{
			return double.Parse(Next());
		}

		public double[] ArrayDouble(int N, double add = 0)
		{
			double[] Array = new double[N];
			for (int i = 0; i < N; i++) {
				Array[i] = Double() + add;
			}
			return Array;
		}
	}
}