#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
#ifdef ENABLE_DEBUG
#define dump(a) cerr<<#a<<"="<<a<<endl
#define dumparr(a,n) cerr<<#a<<"["<<n<<"]="<<a[n]<<endl
#else
#define dump(a) 
#define dumparr(a,n) 
#endif
#define FOR(i, a, b) for(ll i = (ll)a;i < (ll)b;i++)
#define For(i, a) FOR(i, 0, a)
#define REV(i, a, b) for(ll i = (ll)b-1LL;i >= (ll)a;i--)
#define Rev(i, a) REV(i, 0, a)
#define REP(a) For(i, a)
#define SIGN(a) (a==0?0:(a>0?1:-1))

typedef long long int ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<ll, ll> pll;
typedef pair<ll,pll> ppll;
typedef vector<ll> vll;
typedef long double ld;
typedef pair<ld,ld> pdd;

pll operator+(pll a,pll b){
  return pll(a.first+b.first,a.second+b.second);
}
pll operator-(pll a,pll b){
  return pll(a.first-b.first,a.second-b.second);
}
pll operator*(ll a,pll b){
  return pll(b.first*a,b.second*a);
}
const ll INF=(1LL<<60);
#if __cplusplus<201700L
ll gcd(ll a, ll b) {
  a=abs(a);
  b=abs(b);
  if(a==0)return b;
  if(b==0)return a;
  if(a < b) return gcd(b, a);
  ll r;
  while ((r=a%b)) {
    a = b;
    b = r;
  }
  return b;
}
#endif
template<class T>
bool chmax(T& a,const T& b){
  if(a<b){
    a=b;
    return true;
  }
  return false;
}
template<class T>
bool chmin(T& a,const T& b){
  if(a>b){
    a=b;
    return true;
  }
  return false;
}
template<class S,class T>
std::ostream& operator<<(std::ostream& os,pair<S,T> a){
  os << "(" << a.first << "," << a.second << ")";
  return os;
}
template<class T>
std::ostream& operator<<(std::ostream& os,vector<T> a){
  os << "[ ";
  REP(a.size()){
    os<< a[i] << " ";
  }
  os<< " ]";
  return os;
}

const long long MOD = 1000000007;

long long modpow(long long a,unsigned long long b){
  long long base=a,ans=(1LL);
  while(b){
    if(b&1){
      ans=ans*base%MOD;
    }
    base=base*base%MOD;
    b>>=1;
  }
  return ans;
}
long long invpow(long long a){
  return modpow(a,MOD-2);
}
class UF{
  vector<long> par,rank,size_uf;
  long _chunk_size;
public:
  UF(long size):_chunk_size(size){
    for (long i = 0; i < size; i++) {
      par.push_back(i);
      rank.push_back(0);
      size_uf.push_back(1);
    }
  }
  long find(long x){
    if(par[x]==x)return x;
    return par[x]=find(par[x]);
  }
  void unite(long x,long y){
    x=find(x);
    y=find(y);
    if(x==y)return;
    --_chunk_size;
    if(rank[x]<rank[y]){
      par[x]=y;
      size_uf[y]+=size_uf[x];
    }
    else{
      par[y]=x;
      size_uf[x]+=size_uf[y];
      if(rank[x]==rank[y])rank[x]++;
    }
  }
  bool same(long x,long y){
    return find(x)==find(y);
  }
  long operator [](long x){
    return this->find(x);
  }
  long size(long x){
    x=find(x);
    return size_uf[x];
  }
  long chunk_size(){
    return this->_chunk_size;
  }
};

void solve(long long H, long long W, std::vector<std::string> S){
  ll K=0;
  UF uft(H*W),ufy(H*W);
  For(i,H){
    For(j,W){
      if(S[i][j]=='.'){
        ++K;
        if(i<H-1&&S[i+1][j]=='.'){
          uft.unite(W*i+j,W*(i+1)+j);
        }
        if(j<W-1&&S[i][j+1]=='.'){
          ufy.unite(W*i+j,W*i+j+1);
        }
      }
    }
  }
  ll all = modpow(2,K)*K%MOD;
  ll diff=0;
  For(i,H){
    For(j,W){
      if(S[i][j]=='.'){
        ll cnt=uft.size(W*i+j)+ufy.size(W*i+j)-1;
        diff=(diff+modpow(2,K-cnt))%MOD;
      }
    }
  }
  cout<<(MOD+all-diff)%MOD<<endl;
}

int main(){
  cout<<setprecision(1000);
    long long H;
    scanf("%lld",&H);
    long long W;
    scanf("%lld",&W);
    std::vector<std::string> S(H);
    for(int i = 0 ; i < H ; i++){
        std::cin >> S[i];
    }
    solve(H, W, std::move(S));
    return 0;
}

#include <bits/stdc++.h>

#pragma GCC optimize("Ofast")
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
typedef long long ll;
constexpr ll mod = 1e9 + 7;

ll modpow(ll a, ll b) {
  ll r = 1;
  while (b) {
    if (b & 1) r = r * a % mod;
    a = a * a % mod;
    b >>= 1;
  }
  return r;
}

int main() {
  // ios::sync_with_stdio(false);
  // cin.tie(nullptr);
  ll n, w, h, ans = 0, cnt = 0;
  cin >> h >> w;
  string s[h];
  ll tate[h][w] = {}, yoko[h][w] = {};
  rep(i, h) cin >> s[i];
  rep(i, h) rep(j, w) if (s[i][j] == '.') cnt++;


  if (cnt == h * w) {
    ll t = h + w - 1;
    ans = (modpow(2, t) - 1) * modpow(2, h * w - t);
    ans %= mod;
    ans *= h * w;
    ans %= mod;
    cout << ans << endl;
    return 0;
  }
  ans = 0;

  rep(i, h) rep(j, w) {
    if (s[i][j] == '#') continue;
    ll now = 1;
    for (int k = i - 1; k >= 0; --k)
      if (s[k][j] == '.')
        now++;
      else
        break;

    for (int k = i + 1; k < h; ++k)
      if (s[k][j] == '.')
        now++;
      else
        break;

    for (int k = j - 1; k >= 0; --k)
      if (s[i][k] == '.')
        now++;
      else
        break;

    for (int k = j + 1; k < w; ++k)
      if (s[i][k] == '.')
        now++;
      else
        break;

    ll add = (modpow(2, now) - 1) * modpow(2, cnt - now) % mod;
    (ans += add) %= mod;
  }

  cout << ans << endl;
  return 0;
}