//#pragma GCC optimize ("O2")
//#pragma GCC target ("avx2")
//#include<bits/stdc++.h>
//#include<atcoder/all>
//using namespace atcoder;

#include<cstdio>

using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rep1(i, n) for(int i = 1; i <= (n); i++)
#define co(x) cout << (x) << "\n"
#define cosp(x) cout << (x) << " "
#define ce(x) cerr << (x) << "\n"
#define cesp(x) cerr << (x) << " "
#define pb push_back
#define mp make_pair
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
#define Would
#define you
#define please

ll dph[2000], dphw[4000], *naname = dphw + 2000;
const int mod = 1e9 + 7;

int main() {
	//cin.tie(0);
	//ios::sync_with_stdio(false);


	int H = 0, W = 0;
	char c;
	while ((c = getchar_unlocked()) >= '0') H = H * 10 + c - '0';
	while ((c = getchar_unlocked()) >= '0') W = W * 10 + c - '0';


	getchar_unlocked();
	dph[0] = 1;
	naname[0] = 1;
	ll w = 1;
	ll tmp = 1;
	rep1(i, W - 1) {
		tmp = w;
		if (getchar_unlocked() == '.') {
			dph[i] = w;
			naname[i] = w;
			w = w * 2 % mod;
		}
		else {
			dph[i] = 0;
			naname[i] = 0;
			w = 0;
		}
	}
	getchar_unlocked();

	rep1(i, H - 1) {
		if (getchar_unlocked() == '.') {
			tmp = dph[0];
			w = tmp;
			dph[0] = (tmp + dph[0]) % mod;
			naname[-i] = (tmp + naname[-i]) % mod;
		}
		else {
			w = 0;
			dph[0] = 0;
			naname[-i] = 0;
		}
		if (!(i & 7)) {
			rep1(j, W - 1) {
				if (getchar_unlocked() == '.') {
					tmp = w + dph[j] + naname[j - i];
					w += tmp - ll(double(w + tmp) / mod) * mod;
					dph[j] += tmp - ll(double(dph[j] + tmp) / mod) * mod;
					naname[j - i] += tmp - ll(double(tmp + naname[j - i]) / mod) * mod;
				}
				else {
					w = 0;
					dph[j] = 0;
					naname[j - i] = 0;
				}
			}
		}
		else {
			rep1(j, W - 1) {
				if (!(j & 7)) {
					if (getchar_unlocked() == '.') {
						tmp = w + dph[j] + naname[j - i];
						w += tmp - ll(double(w + tmp) / mod) * mod;
						dph[j] += tmp - ll(double(dph[j] + tmp) / mod) * mod;
						naname[j - i] += tmp - ll(double(tmp + naname[j - i]) / mod) * mod;
					}
					else {
						w = 0;
						dph[j] = 0;
						naname[j - i] = 0;
					}
				}
				else {
					if (getchar_unlocked() == '.') {
						tmp = w + dph[j] + naname[j - i];
						w = w + tmp;
						dph[j] = tmp + dph[j];
						naname[j - i] = tmp + naname[j - i];
					}
					else {
						w = 0;
						dph[j] = 0;
						naname[j - i] = 0;
					}
				}
			}
		}
		getchar_unlocked();
	}


	printf("%lld\n", tmp % mod);

	Would you please return 0;
}
#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
#include <random>
using namespace std;
#define ll long long
#define fr first
#define sc second
#define pll pair<ll, ll>
#define all(v) v.begin(), v.end()

const int mod = 1e9 + 7;
int H, W;
char arr[2200][2200];
ll cache[2200][2200][4];
int dy[] = { 1, 0, 1 };
int dx[] = { 0, 1, 1 };

ll dp(int y, int x, int dir) {
	if (y == H - 1 && x == W - 1) return 1;

	ll& ret = cache[y][x][dir];
	if (ret != -1) return ret;

	ret = 0;
	if (x + 1 < W && arr[y][x + 1] != '#') ret = (ret + dp(y, x + 1, 0)) % mod;
	if (y + 1 < H && arr[y + 1][x] != '#') ret = (ret + dp(y + 1, x, 1)) % mod;
	if (y + 1 < H && x + 1 < W && arr[y + 1][x + 1] != '#') ret = (ret + dp(y + 1, x + 1, 2)) % mod;
	
	if (dir == 0 && x + 1 < W && arr[y][x + 1] != '#') ret = (ret + dp(y, x + 1, 0)) % mod;
	if (dir == 1 && y + 1 < H && arr[y + 1][x] != '#') ret = (ret + dp(y + 1, x, 1)) % mod;
	if (dir == 2 && y + 1 < H && x + 1 < W && arr[y + 1][x + 1] != '#') ret = (ret + dp(y + 1, x + 1, 2)) % mod;
	return ret;
}

void solve(int tc) {
	cin >> H >> W;
	for (int i = 0; i < H; i++) cin >> arr[i];
	memset(cache, -1, sizeof(cache));
	cout << dp(0, 0, 3) << '\n';
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	if (0) {
		int T; cin >> T;
		for (int i = 1; i <= T; i++) solve(i);
	}
	else {
		solve(0);
	}
	return 0;
}