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 <iostream>
#include <string>
using namespace std;

const int MOD = 1e9 + 7, MAXN = 3e5 + 10;
long long dpo[8], dp[8], pw[MAXN], ans;
int n, cnt;
string s;

void addme(bool v) {
	dp[1 + v] += dpo[0];
	dp[3 + v] += dpo[1];
	dp[1] += dpo[3];
	dp[5] += dpo[6];
	if (!v) {
		dp[5] += dpo[2];
		dp[1] += dpo[4];
		dp[6] += dpo[5];
	}
	else {
		dp[7] += dpo[2];
		dp[2] += dpo[4];
		dp[2] += dpo[5];
	}
	for (int i = 0; i < 8; i++)
		dp[i] %= MOD;
}

int main() {
	cin >> s;
	n = s.size();
	pw[0] = 1;
	for (int i = 1; i <= n; i++) {
		pw[i] = pw[i - 1] * 2, pw[i] %= MOD;
		cnt += s[i - 1] == '?';
	}
	dpo[0] = 1;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < 8; j++)
			dp[j] = 0;
		if (s[i] == '?')
			addme(0), addme(1), cnt--;
		else if (s[i] == '1')
			addme(1);
		else
			addme(0);
		ans += dp[7] * pw[cnt];
		ans %= MOD;
		swap(dp, dpo);
	}
	ans += dpo[2];
	ans %= MOD;
	cout << ans;
}