//https://atcoder.jp/contests/abc183/tasks/abc183_e
//E - Queen on Grid
#include <bits/stdc++.h>

using namespace std;
const int MAXH=2e3+2;
const int MAXW=2e3+2;
char nums[MAXH][MAXW];//用于保存迷宫

long long row[MAXH];//行走法
long long col[MAXW];//列走法
long long dia[MAXH+MAXW];//对角线

const long long MO=1e9+7;
/*计算对角线的时候 i-j 可能出现负数，最大的负数是 1-2000=-1999，所以需要一个 OFFSET 保证正下标*/
const int OFFSET=max(MAXH, MAXW);//只要超过MAXH和MAXW最大值就可以

int main() {
#if 1
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
#endif
    int h,w;
    cin>>h>>w;
    for (int i=1; i<=h; i++) {
        for (int j=1; j<=w; j++) {
            cin>>nums[i][j];
        }
    }

    long long ans=-1;
    for (int i=1; i<=h; i++) {
        for (int j=1; j<=w; j++) {
            if ('#'==nums[i][j]) {
                row[i] = 0;
                col[j] = 0;
                dia[i-j+OFFSET] = 0;
            } else {
                long long res = (row[i]+col[j]+dia[i-j+OFFSET])%MO;
                if (1==i && 1==j) {
                    res++;
                }
                ans = res;

                //更新
                row[i] = (row[i]+res)%MO;
                col[j] = (col[j]+res)%MO;
                dia[i-j+OFFSET] = (dia[i-j+OFFSET]+res)%MO;
            }
        }
    }

    cout<<ans<<"\n";

    return 0;
}
#include<bits/stdc++.h>
#include<cmath>
#define SZ(x) ((int)x.size())
#include<vector>
#include<set>
#include<map>
#define ll long long
#define lli long long int
#define REP(i,a,b) for(ll i=a;i<b;i++)
#define pb push_back
#include<string>
#include<cctype>
#define F first
#define rep(i,a,b)    for(int i=a;i<b;i++)
#define S second
#include<queue>
#include <sstream>
#define lli long long int
#define pairs pair<int,int>
#define ld long double
#define mod 1000000007;
const double PI = 3.141592653589793238460;
typedef std::complex<double> Complex;
typedef std::valarray<Complex> CArray;
using namespace std;
//first try to write all condition on copy then go for implement
ll pows(ll a,ll n,ll m)
{
	a=a%mod;
	ll res=1;
	while(n)
	{
	if(n%2!=0)
	{
		res=(res*a)%m;
		n--;
		}
		else
		{
			a=(a*a)%m;
			n=n/2;
			}	
	}
	return res%m;
}
int  gcd(int a,int b)
{
	if(b==0)
	return a;
	else 
	return gcd(b,a%b);
}
bool isprime(ll n)
{
	if(n==1)
	{
		return false;
	}
	for(ll i=2;i*i<=n;i++)
	{
		if(n%i==0)
		{
			return false;
		}
	}
	return true;
}
bool istrue(string s)
{
	int i=0;
	int j=s.size()-1;
	while(i<j)
	{
	if(s[i]==s[j])
	{
		i++;
		j--;
		}
		else
		{
		return false;
			}	
	}
	return true;
}

const int N=2005;


 
string s[N];
ll dp[N][N];
ll phor[N][N];
ll pver[N][N];
ll pdia[N][N];
 
bool wall(int x,int y){
	if(x < 1 || y < 1 || s[x-1][y-1] == '#') return true;
	return false;
}
 
int main()
{
ios::sync_with_stdio(false);
	 cin.tie(0);
    cout.tie(0);
int h,w;
	cin >> h >> w;
	rep(i,0,h){
		cin >> s[i];
	}
	
	dp[1][1] = 1;
	phor[1][1] = 1;
	pver[1][1] = 1;
	pdia[1][1] = 1;
	
	rep(i,1,h+1){
		rep(j,1,w+1){
			if(i == 1 && j == 1) continue;
			if(wall(i,j)) continue;
			dp[i][j] = (phor[i-1][j] + pver[i][j-1] + pdia[i-1][j-1]) % mod;
			
			phor[i][j] = dp[i][j];
			pver[i][j] = dp[i][j];
			pdia[i][j] = dp[i][j];
			phor[i][j] += phor[i-1][j];
			pver[i][j] += pver[i][j-1];
			pdia[i][j] += pdia[i-1][j-1];
			
			phor[i][j] %= mod;
			pver[i][j] %= mod;
			pdia[i][j] %= mod;
		}
	}
	
	cout << dp[h][w]<<endl;
}