#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>

#define F first
#define S second
#define int long long
#define ll long long
//#define int  unsigned long long
#define pb push_back
//#define double long double

using namespace std;
using namespace __gnu_pbds;
typedef  tree< int , null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
const int mod = 1e9 + 7;
const int N = 1500000;
const int K = 700 ;
int p[N][3], t[N][3], f1[N], f2[N];
main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    //freopen("input.txt", "r", stdin);
    string s;
    cin >> s;
    int n = s.length();
    if (s[0] == '?'){
        f1[1] = 1;
        p[1][0] = 1;
    } else
    if (s[0] == '1'){
        f1[1] = 1;
    } else{
        p[1][0] = 1;
    }
    if (s[n - 1] == '?'){
        f2[n] = 1;
        t[n][0] = 1;
    } else
    if (s[n - 1] == '1'){
        f2[n] = 1;
    } else
    if (s[n - 1] == '0'){
        t[n][0] = 1;
    }
    for (int i = 2; i <= n; i++){
        if (i % 2){
            if (s[i - 1] == '1'){
                p[i][0] = p[i - 1][0];
                p[i][1] = (p[i - 1][1] + p[i - 1][2]) % mod;
            } else
            if (s[i - 1] == '0'){
                p[i][0] = (p[i - 1][0] + p[i - 1][1]) % mod;
                p[i][1] = (p[i - 1][2]) % mod;
            } else{
                p[i][0] = (2 * p[i - 1][0] + p[i - 1][1]) % mod;
                p[i][1] = (2 * p[i - 1][2] + p[i - 1][1]) % mod;
            }
            f1[i] = p[i][1];
            p[i][1] = 0;
        } else{
            if (s[i - 1] == '1'){
                p[i][1] = p[i - 1][0];
                p[i][2] = p[i - 1][1];
            } else
            if (s[i - 1] == '0'){
                p[i][0] = p[i - 1][0];
                p[i][1] = p[i - 1][1];
            } else{
                p[i][0] = p[i - 1][0];
                p[i][1] = (p[i - 1][1] + p[i - 1][0]) % mod;
                p[i][2] = p[i - 1][1];
            }
        }
    }
    for (int i = n - 1; i >= 1; i--){
        if (i % 2){
            if (s[i - 1] == '1'){
                t[i][0] = t[i + 1][0];
                t[i][1] = (t[i + 1][1] + t[i + 1][2]) % mod;
            } else
            if (s[i - 1] == '0'){
                t[i][0] = (t[i + 1][0] + t[i + 1][1]) % mod;
                t[i][1] = (t[i + 1][2]) % mod;
            } else{
                t[i][0] = (2 * t[i + 1][0] + t[i + 1][1]) % mod;
                t[i][1] = (2 * t[i + 1][2] + t[i + 1][1]) % mod;
            }
            f2[i] = t[i][1];
            t[i][1] = 0;
        } else{
            if (s[i - 1] == '1'){
                t[i][1] = t[i + 1][0];
                t[i][2] = t[i + 1][1];
            } else
            if (s[i - 1] == '0'){
                t[i][0] = t[i + 1][0];
                t[i][1] = t[i + 1][1];
            } else{
                t[i][0] = t[i + 1][0];
                t[i][1] = (t[i + 1][1] + t[i + 1][0]) % mod;
                t[i][2] = t[i + 1][1];
            }
        }
    }
    int x = 0;
    int ans = 0;
    for (int i = 1; i <= n; i++) ans = (ans + f1[i] * f2[i]) % mod;
    for (int i = 1; i <= n; i ++){
        if (i % 2){
            ans = (ans + x * f2[i]) % mod;
        }
        if (s[i - 1] == '?') x = (x + x) % mod;
        if (i % 2) x = (x + f1[i]) % mod;
    }
    cout << (ans) % mod;
}


Measured memory_bytes: 27284