#include<bits/stdc++.h>

using namespace std;

#define INF 1000000007
#define LINF (1LL << 62)
#define PI 3.14159265358979

typedef long long i64;
typedef pair<i64,i64> P;

inline i64 mod(i64 a, i64 m) { return (a % m + m) % m; }

template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }

mt19937_64 rnd(time(NULL));



i64 mod_pow(i64 x, i64 y, i64 mod){
	i64 res = 1;
	while(y > 0){
		if(y & 1) res = res * x % mod;
		x = x*x %mod;
		y >>= 1;
	}
	return res;
}

int h,w;
string s[2020];
int a[2020][2020];
bool used[2020][2020];
void solve(){
	cin >> h >> w;
	for(int i = 0; i < h; i++){
		cin >> s[i];
	}
	i64 l = 0;
	for(int i = 0; i < h; i++){
		for(int j = 0; j < w; j++){
			if(s[i][j] == '.') l++;
		}
	}
	
	for(int i = 0; i < h; i++) fill(a[i],a[i]+w,-1);
	for(int i = 0; i < h; i++){
		for(int j = 0; j < w; j++){
			if(s[i][j] == '#') continue;
			if(used[i][j]) continue;
			int c = j;
			while(s[i][j] == '.' && j < w) j++;
			for(int k = c; k < j; k++){
				a[i][k] += j-c;
			}
		}
	}
	for(int i = 0; i < h; i++) fill(used[i],used[i]+w, 0);
	for(int j = 0; j < w; j++){
		for(int i = 0; i < h; i++){
			if(s[i][j] == '#') continue;
			if(used[i][j]) continue;
			int c = i;
			while(s[i][j] == '.' && i < h) i++;
			for(int k = c; k < i; k++){
				a[k][j] += i-c;
			}
		}
	}
	
	i64 cnt = 0;
	for(int i = 0; i < h; i++){
		for(int j = 0; j < w; j++){
			if(s[i][j] == '#') continue;
			cnt += (mod_pow(2,a[i][j],INF)-1)*mod_pow(2,l-a[i][j],INF);
			cnt %= INF;
		}
	}
	cout << cnt << endl;
}

int main(){
	std::cin.tie(0);
	std::ios::sync_with_stdio(false);
	int t = 1;
	//cin >> t;
	while(t--){
		solve();
	}
	
	return 0;
}

#include <cctype>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>

using namespace std;
#define REP(i, n) for(int i = 0; i < (int)(n); ++i)

typedef long long ll;

long long inv(int a, int p) { return a==1 ? 1 : (1-p*inv(p%a,a))/a+p; }
static const int MODVAL = 1000000007;
struct mint {
  int val;
  mint():val(0){}
  mint(int x):val(x%MODVAL) { if(val<0) val+= MODVAL; }
  mint(size_t x):val(x%MODVAL) {}
  mint(long long x):val(x%MODVAL) { if(val<0) val+= MODVAL; }
  mint& operator+=(mint y) { val+=y.val; if(val>=MODVAL) val-=MODVAL; return *this; }
  mint& operator-=(mint y) { val-=y.val; if(val<0) val+= MODVAL; return *this; }
  mint& operator*=(mint y) { val=(val*(long long)y.val)%MODVAL; return *this; }
  mint& operator/=(mint y) { val=(val*inv(y.val,MODVAL))%MODVAL; return *this; }
};
inline mint operator+(mint x, mint y) { return x+=y; }
inline mint operator-(mint x, mint y) { return x-=y; }
inline mint operator*(mint x, mint y) { return x*=y; }
inline mint operator/(mint x, mint y) { return x/=y; }
mint POW(mint x, long long n) { mint r(1); for(;n;x*=x,n>>=1) if(n&1) r*=x; return r; }
mint FAC(int n) { static vector<mint> FAC_(1,1);
  while(int(FAC_.size())<=n) FAC_.push_back(FAC_.back()*FAC_.size()); return FAC_[n]; }
inline mint CMB(int n, int k) { return k<0||n<k ? 0 : FAC(n) / (FAC(k) * FAC(n-k)); }
inline ostream& operator<<(ostream& os, mint a) { return os << a.val; }

char buf[2010][2010];
int ct[2010][2010];
bool used[2][2010][2010];

int main(void) {
  int h, w;
  scanf("%d%d", &h, &w);
  int empty = 0;
  REP(i, h) {
    scanf("%s", buf[i]);
    REP(j, w) {
      if(buf[i][j] == '.') {
        ++empty;
      }
    }
  }
  REP(i, h) {
    REP(j, w) {
      if(buf[i][j] != '.') {
        continue;
      }
      if(!used[0][i][j]) {
        int c = 0;
        for(int ii = i; ii < h && buf[ii][j] == '.'; ++ii) {
          ++c;
        }
        for(int ii = i; ii < h && buf[ii][j] == '.'; ++ii) {
          ct[ii][j] += c;
          used[0][ii][j] = true;
        }
      }
      if(!used[1][i][j]) {
        int c = 0;
        for(int jj = j; jj < w && buf[i][jj] == '.'; ++jj) {
          ++c;
        }
        for(int jj = j; jj < w && buf[i][jj] == '.'; ++jj) {
          ct[i][jj] += c;
          used[1][i][jj] = true;
        }
      }
    }
  }
  
  mint res = empty * POW(2, empty);
  REP(i, h) {
    REP(j, w) {
      if(buf[i][j] == '#') {
        continue;
      }
      // cerr << ct[i][j] << " ";
      // cerr << POW(2, empty-ct[i][j]+1) << " ";
      res -= POW(2, empty-ct[i][j]+1);
    }
    // cerr << endl;
  }
  cout << res << endl;
  return 0;
}
