#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;
}

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
const int M = 300005;
int read()
{
	int x=0,f=1;char c;
	while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
	while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
	return x*f;
}
int n,m,tot,f[M],dis[M];
struct edge
{
    int v,c,next;
}e[10*M];
struct node
{
    int u,c;
    bool operator < (const node &R) const
    {
        return c>R.c;
    }
};
int id(int x,int y)
{
    return (x-1)*m+y;
}
void add(int u,int v,int c)
{
    e[++tot]=edge{v,c,f[u]},f[u]=tot;
}
void dijk()
{
    priority_queue<node> q;
    memset(dis,0x3f,sizeof dis);
    q.push(node{1,0});dis[1]=0;
    while(!q.empty())
    {
        int u=q.top().u,t=q.top().c;q.pop();
        if(t>dis[u]) continue;
        for(int i=f[u];i;i=e[i].next)
        {
            int v=e[i].v,c=e[i].c;
            if(dis[v]>dis[u]+c)
            {
                dis[v]=dis[u]+c;
                q.push(node{v,dis[v]});
            }
        }
        int x=(u-1)/m+1,y=(u-1)%m+1;
        for(int i=1;i<x;i++)
        {
            int v=id(x-i,y),c=i+1;
            if(dis[v]>dis[u]+c)
            {
                dis[v]=dis[u]+c;
                q.push(node{v,dis[v]});
            }
        }
    }
}
signed main()
{
    n=read();m=read();
    for(int i=1;i<=n;i++)
        for(int j=1;j<m;j++)
        {
            int x=read();
            add(id(i,j),id(i,j+1),x);
            add(id(i,j+1),id(i,j),x);
        }
    for(int i=1;i<n;i++)
        for(int j=1;j<=m;j++)
        {
            int x=read();
            add(id(i,j),id(i+1,j),x);
        }
    dijk();
    printf("%d\n",dis[id(n,m)]);
}
