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<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int MOD = 1000000007;
const int maxn = 300000 + 10;

inline int inc(int a, int b) { return (a + b >= MOD) ? (a + b - MOD) : (a + b); }
inline int dec(int a, int b) { return (a >= b) ? (a - b) : (a + MOD - b); }
inline int mul(int a, int b) { return 1LL * a * b % MOD; }
 
inline void updata(int &x, int y) { x = inc(x,y); }
 
inline int power(int x, int k) {
  int tmp = 1;
  while(k) {
    if(k & 1) tmp = mul(tmp,x);
    x = mul(x,x);
    k >>= 1;
  }
  return tmp;
}

char s[maxn];
int n, dp[maxn][7];

inline int encode(string s) {
	int Sz = s.size();
	if(!Sz) return 0;
	if(Sz == 3) return 6;
	if(Sz == 1) {
		if(s[0] == '0') return 3;
		else return 1;
	}
	if(s[0] == '0') return 4;
	if(s[1] == '1') return 2;
	else return 5;
}

inline string decode(int x) {
	if(x == 0) return "";
	if(x == 1) return "1";
	if(x == 2) return "11";
	if(x == 3) return "0";
	if(x == 4) return "00";
	if(x == 5) return "10";
	if(x == 6) return "100";
}

int trans[7][2];
int main() {
//	freopen("data1.in","r",stdin);
	scanf("%s", s + 1); n = strlen(s + 1);
	trans[0][0] = 3; trans[0][1] = 1;
	trans[1][0] = 5; trans[1][1] = 2;
	trans[2][0] = 2; trans[2][1] = 2;
	trans[3][0] = 4; trans[3][1] = 0;
	trans[4][0] = 3; trans[4][1] = 3;
	trans[5][0] = 6; trans[5][1] = 1;
	trans[6][0] = 5; trans[6][1] = 5;
	dp[0][0] = 1;
	for(int i = 1;i <= n;i ++) {
		for(int j = 0;j <= 6;j ++) {
			if(s[i] != '0') updata(dp[i][trans[j][1]],dp[i - 1][j]);
			if(s[i] != '1') updata(dp[i][trans[j][0]],dp[i - 1][j]);
		}
	}
	int Ans = inc(dp[n][1],dp[n][2]);
	printf("%d\n", Ans);
	return 0;
}