#include <bits/stdc++.h>
using namespace std;
char s[1000014];
int dp[1000014][4][5], r, n, ts;
int getsave(char x) {
  if (x == '0')
    return 0;
  else if (x == '1')
    return 1;
  else if (x == '2')
    return 2;
  else if (x == '*')
    return 3;
  else
    return 4;
}
int go(int x, char es, char ls) {
  if (x < 0) return 0;
  if (s[x] != '?' && s[x] != es) return dp[x][getsave(es)][getsave(ls)] = 0;
  if (dp[x][getsave(es)][getsave(ls)] != -1)
    return dp[x][getsave(es)][getsave(ls)];
  int res = 0;
  if (es == '*') {
    if (!x) ++res;
    res += go(x - 1, '1', '*');
    res %= 1000000007;
    res += go(x - 1, '2', '*');
    res %= 1000000007;
    res += go(x - 1, '*', '*');
    res %= 1000000007;
  } else if (es == '0') {
    if (ls == '*') return dp[x][getsave(es)][getsave(ls)] = 0;
    if (!x) res++;
    res += go(x - 1, '0', '0');
    res %= 1000000007;
    res += go(x - 1, '1', '0');
    res %= 1000000007;
  } else if (es == '1') {
    if (ls != '*') {
      if (!x) return dp[x][getsave(es)][getsave(ls)] = 0;
      res += go(x - 1, '*', '1');
      res %= 1000000007;
    } else {
      if (!x) res++;
      res += go(x - 1, '1', '1');
      res %= 1000000007;
      res += go(x - 1, '0', '1');
      res %= 1000000007;
    }
  } else {
    if (!x || ls != '*') return dp[x][getsave(es)][getsave(ls)] = 0;
    res += go(x - 1, '*', '2');
    res %= 1000000007;
  }
  return dp[x][getsave(es)][getsave(ls)] = (res % 1000000007);
}
int main() {
  for (int i = (0); i < (1000014); i++)
    for (int j = (0); j < (4); j++)
      memset((dp[i][j]), (-1), sizeof((dp[i][j])));
  scanf("%s", s);
  r = 0;
  n = strlen(s);
  if (s[n - 1] == '?') {
    r += go(n - 1, '*', 'X');
    r += go(n - 1, '0', 'X');
    r %= 1000000007;
    r += go(n - 1, '1', 'X');
    r %= 1000000007;
    r += go(n - 1, '2', 'X');
    r %= 1000000007;
  } else
    r = go(n - 1, s[n - 1], 'X');
  printf("%d\n", r);
  return 0;
}
