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.Text;
using System.Linq;

namespace codeTester.contest190727
{
    class ProblemD
    {
        static readonly long remainderBase = 1000000007;

        static string s = "";
        static List<long> values = new List<long>();
        static List<long> tmps = new List<long>();
        static List<long> answers = new List<long>();
        static List<long> remainderOfTemPowers = new List<long>();

        public static void Main(string[] args)
        {
            Input();
            Preprocess();
            Logic();
            Output();
        }

        static void Input()
        {
            s = Console.ReadLine();
        }

        public static List<long> ReadSpaceSeparatedValues()
        {
            List<long> values = new List<long>();
            string[] inputs = Console.ReadLine().Split(' ');
            foreach (string input in inputs)
            {
                values.Add(long.Parse(input));
            }

            return values;
        }

        static void Preprocess()
        {
            // 1 から 10000...000（0 が 9999個）までの数それぞれの 13 で割った余りを保存しておく
            // つまり、その桁の数値を１増やしたら、全体を 13 で割った余りがどうなるかを判断する。
            long lastValue = 1;
            for (int i = 0; i < 10000; i++)
            {
                lastValue %= 13;
                remainderOfTemPowers.Add(lastValue);
                lastValue *= 10;
            }
        }

        static void Logic()
        {
            List<long> remainders = new List<long>(); // 余りが 0 になるパターン数 ～ 12 になるパターン数までを全て保存しておく。
            int n = s.Length; // 文字数を取得

            for (int i = 0; i < 13; i++)
            {
                remainders.Add(0);
            }

            // 初期化
            if (s[0] == '?')
            {
                long upValue = remainderOfTemPowers[n - 1];
                for(int j = 0; j < 10; j++)
                {
                    int digit = (int)upValue * j;
                    remainders[digit % 13]++;
                }
            }
            else
            {
                int digit = int.Parse(s[0].ToString());
                remainders[digit % 13]++;
            }


            // 最上位桁からの計算になるな。
            for (int i = 1; i < n; i++)
            {
                char digitChar = s[i];

                // 今の桁数から、どの tenPowersValue を使うべきか判断する
                long upValue = remainderOfTemPowers[n - i - 1];

                // 次の状態を示すテーブル
                List<long> nextRemainders = new List<long>();

                if (digitChar == '?')
                {
                    for (int j = 0; j < 13; j++)
                    {
                        long nextValue = 0;

                        // 枠 j に入れる値を生成する。
                        for (int k = 0; k < 10; k++)
                        {
                            int digit = ((int)upValue * k) % 13; // この桁を k にすることで余りの値がいくつ変化するか
                            int beforePoint = (j - digit + 13) % 13;
                            nextValue += remainders[beforePoint];
                            nextValue = nextValue % remainderBase;
                        }

                        nextRemainders.Add(nextValue % remainderBase);
                    }

                    remainders = nextRemainders;

                }
                else
                {
                    // 特定の数値なので、その分 remainders テーブルを回転させる
                    int digit = ((int)upValue * int.Parse(digitChar.ToString())) % 13;

                    for (int j = 0; j < 13; j++)
                    {
                        // 枠 j に入れる値はどこから持ってくるべきか
                        int beforePoint = (j - digit + 13) % 13;

                        // 枠に値を追加
                        nextRemainders.Add(remainders[beforePoint]);
                    }
                    remainders = nextRemainders;
                }
            }

            answers = remainders;
        }

        static void Output()
        {
            Console.WriteLine(answers[5]);
        }

        static void DebugPrint(string msg)
        {
            // 提出時に消す
            // Console.WriteLine(msg);
        }
    }
}