Problem:
Score : 1600 points

Problem Statement

Taichi thinks a binary string X of odd length N is beautiful if it is possible to apply the following operation \frac{N-1}{2} times so that the only character of the resulting string is 1 :

Choose three consecutive bits of X and replace them by their median. For example, we can turn 00110 into 010 by applying the operation to the middle three bits.

Taichi has a string S consisting of characters 0, 1 and ?. Taichi wants to know the number of ways to replace the question marks with 1 or 0 so that the resulting string is beautiful, modulo 10^{9} + 7.

Constraints

1 \leq |S| \leq 300000

|S| is odd.

All characters of S are either 0, 1 or ?.

Input

Input is given from Standard Input in the following format:

S

Output

Print the number of ways to replace the question marks so that the resulting string is beautiful, modulo 10^{9} + 7.

Sample Input 1

1??00

Sample Output 1

2

There are 4 ways to replace the question marks with 0 or 1 :

11100 : This string is beautiful because we can first perform the operation on the last 3 bits to get 110 and then on the only 3 bits to get 1.

11000 : This string is beautiful because we can first perform the operation on the last 3 bits to get 110 and then on the only 3 bits to get 1.

10100 : This string is not beautiful because there is no sequence of operations such that the final string is 1.

10000 : This string is not beautiful because there is no sequence of operations such that the final string is 1.

Thus, there are 2 ways to form a beautiful string.

Sample Input 2

?

Sample Output 2

1

In this case, 1 is the only beautiful string.

Sample Input 3

?0101???10???00?1???????????????0????????????1????0

Sample Output 3

402589311

Remember to output your answer modulo 10^{9} + 7.

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;

const int64_t MOD = 1e9+7;
void add(int64_t& a, int64_t b){
    a = (a+b) % MOD;
}

int main(){
    string S;
    cin >> S;
    int N = S.size();
    // idx, 1個前, 0ゾーンの長さの偶奇, 1が連続中かどうか, 収支+2
    static int64_t dp[300001][2][2][2][6];
    dp[0][0][0][0][2] = 1;
    for(int i=0; i<N; i++) for(int b=0; b<2; b++) for(int z=0; z<2; z++) for(int l=0; l<2; l++) for(int g=0; g<6; g++){
        int64_t v = dp[i][b][z][l][g];
        if(v == 0) continue;
        for(int a=0; a<2; a++) if(S[i] - '0' != 1-a){
            int b2 = a, z2 = z, l2 = l, g2 = g;
            if(a && (b || i==0 || i==N-1)){
                l2 = 1;
                if(l){
                    g2++;
                }else{
                    if(b) z2 = 1-z;
                    if(i > 0) g2 -= 2-z2;
                    g2 += 1+b;
                    z2 = 0;
                }
            }else{
                l2 = 0;
                z2 = 1-z;
            }
            g2 = min(5, g2);
            add(dp[i+1][b2][z2][l2][g2], v);
        }
    }

    int64_t ans = 0;
    for(int b=0; b<2; b++) for(int z=0; z<2; z++) for(int l=0; l<2; l++) for(int g=0; g<6; g++){
        int g2 = g;
        if(!l) g2 -= 2-z;
        if(g2 > 2) add(ans, dp[N][b][z][l][g]);
    }
    cout << ans << endl;
}