#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define rep(i, n) for (int i = 0; i < (int)(n); i++) #define rep2(i, s, n) for (int i = (int)(s); i < (int)(n); i++) #define repb(i, e) for (int i = (int)(e); i >= 0; i--) #define all(x) x.begin(), x.end() using namespace std; using ll = long long; using ull = unsigned long long; using vi = vector; using vll = vector; using vd = vector; using vvi = vector; using vvll = vector; using vvd = vector; using vs = vector; using vb = vector; using vvb = vector; using vc = vector; using vvc = vector; using pii = pair; using pll = pair; using pil = pair; using pli = pair; using vpii = vector; using vpll = vector; using vpil = vector; using vpli = vector; const double PI = acos(-1); const ll MOD = 1000000007; const ll MODL = 2147483647; const int INF = 1000000007; const ll INFL = 1LL<<60; template inline bool chmin(T &a, T b) {if (a > b) {a = b; return true;} return false;} template inline bool chmax(T &a, T b) {if (a < b) {a = b; return true;} return false;} // template T gcd(T a, T b) {if (a < b) swap(a, b); if (b == 0) return a; else return gcd(b, a%b);} template inline T ceil(T a, T b) {return (a+(b-1))/b;} template inline T floor(T a, T b) {return a/b;} template inline void add(T &a, T b, T m) {a = ((a % m + b % m)) % m;} template inline void sub(T &a, T b, T m) {a = ((a % m - b % m) + m) % m;} template inline void mul(T &a, T b, T m) {a = (((a % m + m) % m) * ((b % m) + m) % m) % m;} vector F(1000009, -1); ll Power(ll a, ll b, ll m) { ll ans = 1, func = a; while (b > 0) { if (b % 2 == 1) { ans = (ans * func) % m; } func = (func * func) % m; b /= 2; } return ans; } ll Modinv(ll a, ll m) { ll b = m, u = 1, v = 0; while (b) { ll t = a / b; a -= t*b; u -= t*v; swap(a, b); swap(u, v); } u %= m; if (u < 0) u += m; return u; } ll Fact(ll a, ll m) { if (F[a] != -1) return F[a]; if (a == 0) return F[a] = 1; return F[a] = (a * Fact(a-1, m)) % m; } ll Perm(ll a, ll b, ll m) { if (a < b || b < 0) return 0; ll ans = Fact(a, m); mul(ans, Modinv(Fact(a-b, m), m), m); return ans; } ll Comb(ll a, ll b, ll m) { if (a < b || b < 0) return 0; ll ans = Fact(a, m); ans = (ans*Modinv(Fact(b, m), m)) % m; ans = (ans*Modinv(Fact(a-b, m), m)) % m; return ans; } int main() { int h, w, now, v; ll num1 = 0, num2 = 0, ans = 0; bool okh = true, okw = true, ok0 = true, ok1 = true; cin >> h >> w; vs s(h); rep(i, h) cin >> s[i]; rep(i, w) { now = -1; rep(j, h) { if (s[j][i] != '?') { v = (int)(s[j][i] - '0'); if (now == -1) now = (v + j) % 2; else if (now != (v + j) % 2) okh = false; } } if (now == -1) num1++; else { if ((now + i) % 2 == 0) ok0 = false; else ok1 = false; } } rep(i, h) { now = -1; rep(j, w) { if (s[i][j] != '?') { v = (int)(s[i][j] - '0'); if (now == -1) now = (v + j) % 2; else if (now != (v + j) % 2) okw = false; } } if (now == -1) num2++; } if (okh) add(ans, Power(2ll, num1, MOD), MOD); if (okw) add(ans, Power(2ll, num2, MOD), MOD); if (ok0) sub(ans, 1ll, MOD); if (ok1) sub(ans, 1ll, MOD); if (!okh && !okw) ans = 0; cout << ans << endl; }