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: Wrong Answer)

using System;
using System.Collections.Generic;
using System.Linq;

class WithIndex<T>
{
    public T Value;
    public int Index;
    public WithIndex(T value, int index)
    {
        this.Value = value;
        this.Index = index;
    }
}

class Power
{
    public int digit;
    public int residualPower;
    public Power(int digit, int residualPower)
    {
        this.digit = digit;
        this.residualPower = residualPower;
    }
}

static class Template
{
    public static int LineToInt()
    {
        return int.Parse(Console.ReadLine());
    }

    public static string[] LineToStrings()
    {
        return Console.ReadLine().Split();
    }

    public static int[] LineToInts()
    {
        return LineToStrings()
            .Select(s => int.Parse(s))
            .ToArray();
    }


    public static int[,] LinesToIntTable(int lineCount, int columnCount)
    {
        var value = new int[lineCount, columnCount];
        foreach (var y in Enumerable.Range(0, lineCount))
        {
            var ints = LineToInts();
            foreach (var x in Enumerable.Range(0, columnCount))
            {
                value[y, x] = ints[x];
            }
        }
        return value;
    }

    public static IEnumerable<WithIndex<T>> WithIndex<T>(this IEnumerable<T> sequence)
    {
        int index = 0;
        foreach (var item in sequence)
        {
            yield return new WithIndex<T>(item, index);
            index++;
        }
    }

    static int at(string s, int digit)
    {
        return s[digit - 1];
    }
    static Dictionary<long, long> memo = new Dictionary<long, long>();
    static long fact(long n)
    {
        if (n == 0)
        {
            if (!memo.ContainsKey(0)) memo.Add(0, 1);
            return 1;
        }
        if (memo.ContainsKey(n)) return memo[n];
        var f = n * fact(n - 1) % 1000000007;
        memo.Add(n, f);
        return f;
    }
    static long combi(int n, int r)
    {
        return fact(n) / (fact(n - r) * fact(r));
    }
    static int residualAtPower(int digit)
    {
        switch (digit % 6)
        {
            case 0: return 1;
            case 1: return 10;
            case 2: return 9;
            case 3: return 12;
            case 4: return 3;
            case 5: return 4;
            default: throw new Exception("aaaa");
        }
    }
    static void Main(string[] args)
    {
        var input = Console.ReadLine();
        var withDigit = input.WithIndex()
            .Select(item => new WithIndex<char>(item.Value, item.Index + 1))
            .ToArray();
        var clearResidual = withDigit
            .Where(item => item.Value != '?')
            .Select(item => (item.Value - '0') * residualAtPower(item.Index))
            .Sum() % 13;
        var shouldResidual = 5 - clearResidual;
        while (shouldResidual < 0) shouldResidual += 13;
        var unknown = withDigit
            .Where(item => item.Value == '?')
            .Select(item => new Power(item.Index, residualAtPower(item.Index)))
            .ToArray();
        //6個いかのグループにまとまっている
        var unknownGroup = unknown
            .GroupBy(u => u.residualPower)
            .ToArray();
        var groupCounts = unknownGroup
            .Select(g => g.Count())
            .ToArray();
        var index = 0;
        var max = Math.Pow(10, unknownGroup.Length);
        long patternCount = 0;
        var multiplers = new int[unknownGroup.Length];
        while (index < max)
        {
            var tempIndex = index;
            var residualSum = 0;
            for (int i = 0; i < unknownGroup.Length; i++)
            {
                multiplers[i] = tempIndex % 10;
                tempIndex /= 10;

                residualSum += unknownGroup[i].Key * multiplers[i];
            }
            residualSum %= 13;
            //
            if (residualSum == shouldResidual)
            {
                long[] tempPatterns = new long[unknownGroup.Length];
                for (int i = 0; i < unknownGroup.Length; i++)
                {
                    //合計値がこの数
                    var takeCountSum = multiplers[i];
                    //何桁ある
                    var digits = groupCounts[i];
                    //
                    long tempPattern = combi(takeCountSum + digits - 1, digits - 1);
                    tempPatterns[i] = tempPattern;
                    //patternCount += tempPattern;
                    while (patternCount > 1000000007)
                    {
                        patternCount -= 1000000007;
                    }
                }
                long p = 1;
                foreach (var t in tempPatterns)
                {
                    p *= t;
                    while (p > 1000000007)
                    {
                        p -= 1000000007;
                    }
                }
                patternCount += p;
                while (patternCount > 1000000007)
                {
                    patternCount -= 1000000007;
                }
            }
            //
            index++;
        }
        Console.WriteLine(patternCount);
    }
}