// Template
#include "bits/stdc++.h"
#define rep_override(x, y, z, name, ...) name
#define rep2(i, n) for (int i = 0; i < (int)(n); ++i)
#define rep3(i, l, r) for (int i = (int)(l); i < (int)(r); ++i)
#define rep(...) rep_override(__VA_ARGS__, rep3, rep2)(__VA_ARGS__)
#define per(i, n) for (ll i = (ll)(n) - 1; i >= 0; --i)
#define all(x) (x).begin(), (x).end()
using namespace std;
using ll = long long;
constexpr int inf = 1001001001;
constexpr ll INF = 3003003003003003003LL;
template <typename T>
inline bool chmin(T &x, const T &y) {
    if (x > y) {
        x = y;
        return true;
    }
    return false;
}
template <typename T> 
inline bool chmax(T &x, const T &y) {
    if (x < y) {
        x = y;
        return true;
    }
    return false;
}
struct IOSET {
    IOSET() {
        cin.tie(nullptr);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(10);
    }
} ioset;
template <typename T>
istream &operator>>(istream &is, vector<T> &vec) {
    for (T &element : vec) is >> element;
    return is;
}
template <typename T>
vector<T> operator--(vector<T> &vec) {
    for (T &element : vec) --element;
    return vec;
}

// Mod-Int
template <int MOD> // MOD > 1
struct ModInt {
    static_assert(MOD >= 1);
    long long val;
    ModInt() = default;
    ModInt(long long x) : val(x % MOD + (x < 0 ? MOD : 0)) {}
    ModInt<MOD> &operator+= (const ModInt<MOD> &x) {
        if ((val += x.val) >= MOD) val -= MOD;
        return *this;
    }
    ModInt<MOD> &operator-= (const ModInt<MOD> &x) {
        if ((val -= x.val) < 0) val += MOD; 
        return *this;
    }
    ModInt<MOD> &operator*= (const ModInt<MOD> &x) {
        (val *= x.val) %= MOD; return *this;
    }
    ModInt<MOD> operator+ (const ModInt<MOD> &x) const {
        return ModInt(*this) += x;
    }
    ModInt<MOD> operator- (const ModInt<MOD> &x) const {
        return ModInt(*this) -= x;
    }
    ModInt<MOD> operator* (const ModInt<MOD> &x) const {
        return ModInt(*this) *= x;
    }
    ModInt<MOD> pow(long long t) const {
        assert(t >= 0);
        ModInt<MOD> res(1), now(*this);
        while (t) {
            if (t & 1) res *= now;
            now *= now;
            t >>= 1;
        }
        return res;
    }
    ModInt<MOD> inv() const {
        return pow(MOD - 2);
    }
    ModInt<MOD> &operator/= (const ModInt<MOD> &x) {
        return *this *= x.pow(MOD - 2);
    }
    ModInt<MOD> operator/ (const ModInt<MOD> &x) const {
        return ModInt(*this) /= x;
    }
    friend std::istream &operator>> (std::istream &is, ModInt<MOD> &x) {
        long long a;
        is >> a;
        x = ModInt<MOD>(a);
        return is;
    }
    friend std::ostream &operator<< (std::ostream &os, const ModInt<MOD> &x) {
        os << x.val;
        return os;
    }
};

constexpr int mod = 1000000007;
using mint = ModInt<mod>;

// Main
int main() {
    int h, w;
    cin >> h >> w;
    vector<string> s(h);
    rep(i, h) cin >> s[i];
    
    int k = 0;
    rep(i, h) rep(j, w) if (s[i][j] == '.') ++k;
    
    vector<vector<int>> a(h, vector<int>(w, 0));
    rep(i, h) rep(j, w) {
        if (s[i][j] == '.') ++a[i][j];
    }
    vector<vector<int>> b = a, c = a, d = a;
    rep(i, h) rep(j, w - 1) {
        if (s[i][j] == '.') a[i][j + 1] += a[i][j];
    }
    rep(i, h) for (int j = w - 1; j > 0; --j) {
        if (s[i][j] == '.') b[i][j - 1] += b[i][j];
    }
    rep(i, h - 1) rep(j, w) {
        if (s[i][j] == '.') c[i + 1][j] += c[i][j];
    }
    for (int i = h - 1; i > 0; --i) rep(j, w) {
        if (s[i][j] == '.') d[i - 1][j] += d[i][j];
    }
    
    mint ans(0);
    rep(i, h) rep(j, w) {
        if (s[i][j] == '#') continue;
        int x = a[i][j] + b[i][j] + c[i][j] + d[i][j] - 3;
        ans += (mint(2).pow(x) - mint(1)) * mint(2).pow(k - x);
    }
    cout << ans << "\n";
}
#include <bits/stdc++.h>
//#include <boost/multiprecision/cpp_int.hpp>
using namespace std;
//using namespace boost::multiprecision;
typedef long long int ll;
typedef long double ld;
typedef pair<ll,ll> P;
#define PI 3.141592653589793
#define MOD 1000000007
//#define MOD 998244353
#define ALL(obj) (obj).begin(),(obj).end()
const ll INF = 1LL << 60;
//四方向への移動ベクトル
const int dx[4] = {1, 0, -1, 0};

struct edge{//グラフに使うヤツ
    ll from,to,cost;
};

typedef vector<vector<edge> > G;

ll gcd(ll a,ll b){
    if (a%b==0)return(b);
    else return(gcd(b,a%b));
}

ll myPow(ll x,ll n,ll m){
  if(n == 0)
    return 1;
  if(n % 2 == 0)
    return myPow(x * x % m, n / 2, m);
  else
    return x * myPow(x, n - 1, m) % m;
}

ll modinv(ll a, ll m) {
    ll b = m, u = 1, v = 0;
    while (b) {
        ll t = a / b;
        a -= t * b; swap(a, b);
        u -= t * v; swap(u, v);
    }
    u %= m;
    if (u < 0) u += m;
    return u;
}

int main(){
    ll h,w;
    cin >> h >> w;
    string s[h];
    for (ll i=0;i<h;i++)cin >> s[i];
    ll tate[h][w],yoko[h][w];
    memset(tate,-1,sizeof(tate));
    memset(yoko,-1,sizeof(yoko));
    ll lc=0;
    for (ll i=0;i<h;i++){
        for (ll j=0;j<w;j++){
            ll c=0,f=j;
            for (ll k=j;s[i][k]=='.' and k<w;k++){
                c++;
                f=k;
                lc++;
            }
            for (ll k=j;k<=f;k++){
                yoko[i][k]=c;
            }
            j=f;
        }
    }
    for (ll i=0;i<w;i++){
        for (ll j=0;j<h;j++){
            ll c=0,f=j;
            for (ll k=j;s[k][i]=='.' and k<h;k++){
                c++;
                f=k;
            }
            for (ll k=j;k<=f;k++){
                tate[k][i]=c;
            }
            j=f;
        }
    }
    ll ans=0;
    ll lcm=myPow(2,lc,MOD),inv=modinv(2,MOD);
    int ni[h+w+10];
    ll a=1;
    for (ll i=0;i<h+w+5;i++){
        ni[i]=a;
        a*=2;
        a%=MOD;
    }
    for (ll i=0;i<h;i++){
        for (ll j=0;j<w;j++){
            if (s[i][j]=='.'){
                ll c=tate[i][j]+yoko[i][j]-1;
                c=ni[c];
                ll x=(c-1)*lcm%MOD;
                x*=modinv(c,MOD);
                x%=MOD;
                ans+=x;
                ans%=MOD;
            }
        }
    }
    cout << ans << endl;
    return 0;
}
