#include <bits/stdc++.h>
using namespace std;
template <typename T> void setmax(T& a, T b) { if (b > a) a = b; }
using i64 = int64_t;
const int MOD = 1e9 + 7;
const int MAXN = 1010;
const int MAXM = 1010;
int N, M;
char G[MAXN][MAXM];
const int MAXV = MAXN * MAXM;
int V;
int par[MAXV];
int ways[MAXV];
void reset() {
for (int v = 0; v < V; v++) {
par[v] = -1;
ways[v] = 1;
}
}
int getPar(int a) {
return par[a] < 0 ? a : (par[a] = getPar(par[a]));
}
void merge(int a, int b) {
a = getPar(a), b = getPar(b);
if (a == b) return;
if (a > b) swap(a, b);
ways[a] = i64(ways[a]) * ways[b] % MOD;
par[b] = a;
}
int vert(int i, int j) {
return i * M + j;
}
int main() {
ios::sync_with_stdio(0), cin.tie(0);
cin >> N >> M;
for (int i = 0; i < N; i++) {
cin >> G[i];
}
V = N * M;
reset();
for (int i = N-1; i >= 0; i--) {
for (int j = 0; j < M; j++) {
if (i+1 < N && G[i][j] == '.' && G[i+1][j] == '.') {
merge(vert(i, j), vert(i+1, j));
}
if (j+1 < M && G[i][j] == '.' && G[i][j+1] == '.') {
merge(vert(i, j), vert(i, j+1));
}
}
for (int j = 0; j < M; j++) {
if (G[i][j] == '.' && getPar(vert(i, j)) == vert(i, j)) {
ways[vert(i, j)]++;
}
}
}
int ans = 1;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (G[i][j] == '.' && getPar(vert(i, j)) == vert(i, j)) {
ans = i64(ans) * ways[vert(i, j)] % MOD;
}
}
}
cout << ans << '\n';
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gdm9pZCBzZXRtYXgoVCYgYSwgVCBiKSB7IGlmIChiID4gYSkgYSA9IGI7IH0KCnVzaW5nIGk2NCA9IGludDY0X3Q7Cgpjb25zdCBpbnQgTU9EID0gMWU5ICsgNzsKCmNvbnN0IGludCBNQVhOID0gMTAxMDsKY29uc3QgaW50IE1BWE0gPSAxMDEwOwppbnQgTiwgTTsKY2hhciBHW01BWE5dW01BWE1dOwoKY29uc3QgaW50IE1BWFYgPSBNQVhOICogTUFYTTsKaW50IFY7CmludCBwYXJbTUFYVl07CmludCB3YXlzW01BWFZdOwp2b2lkIHJlc2V0KCkgewoJZm9yIChpbnQgdiA9IDA7IHYgPCBWOyB2KyspIHsKCQlwYXJbdl0gPSAtMTsKCQl3YXlzW3ZdID0gMTsKCX0KfQppbnQgZ2V0UGFyKGludCBhKSB7CglyZXR1cm4gcGFyW2FdIDwgMCA/IGEgOiAocGFyW2FdID0gZ2V0UGFyKHBhclthXSkpOwp9CnZvaWQgbWVyZ2UoaW50IGEsIGludCBiKSB7CglhID0gZ2V0UGFyKGEpLCBiID0gZ2V0UGFyKGIpOwoJaWYgKGEgPT0gYikgcmV0dXJuOwoJaWYgKGEgPiBiKSBzd2FwKGEsIGIpOwoJd2F5c1thXSA9IGk2NCh3YXlzW2FdKSAqIHdheXNbYl0gJSBNT0Q7CglwYXJbYl0gPSBhOwp9CgppbnQgdmVydChpbnQgaSwgaW50IGopIHsKCXJldHVybiBpICogTSArIGo7Cn0KCmludCBtYWluKCkgewoJaW9zOjpzeW5jX3dpdGhfc3RkaW8oMCksIGNpbi50aWUoMCk7CgljaW4gPj4gTiA+PiBNOwoJZm9yIChpbnQgaSA9IDA7IGkgPCBOOyBpKyspIHsKCQljaW4gPj4gR1tpXTsKCX0KCglWID0gTiAqIE07CglyZXNldCgpOwoKCWZvciAoaW50IGkgPSBOLTE7IGkgPj0gMDsgaS0tKSB7CgkJZm9yIChpbnQgaiA9IDA7IGogPCBNOyBqKyspIHsKCQkJaWYgKGkrMSA8IE4gJiYgR1tpXVtqXSA9PSAnLicgJiYgR1tpKzFdW2pdID09ICcuJykgewoJCQkJbWVyZ2UodmVydChpLCBqKSwgdmVydChpKzEsIGopKTsKCQkJfQoJCQlpZiAoaisxIDwgTSAmJiBHW2ldW2pdID09ICcuJyAmJiBHW2ldW2orMV0gPT0gJy4nKSB7CgkJCQltZXJnZSh2ZXJ0KGksIGopLCB2ZXJ0KGksIGorMSkpOwoJCQl9CgkJfQoKCQlmb3IgKGludCBqID0gMDsgaiA8IE07IGorKykgewoJCQlpZiAoR1tpXVtqXSA9PSAnLicgJiYgZ2V0UGFyKHZlcnQoaSwgaikpID09IHZlcnQoaSwgaikpIHsKCQkJCXdheXNbdmVydChpLCBqKV0rKzsKCQkJfQoJCX0KCX0KCglpbnQgYW5zID0gMTsKCWZvciAoaW50IGkgPSAwOyBpIDwgTjsgaSsrKSB7CgkJZm9yIChpbnQgaiA9IDA7IGogPCBNOyBqKyspIHsKCQkJaWYgKEdbaV1bal0gPT0gJy4nICYmIGdldFBhcih2ZXJ0KGksIGopKSA9PSB2ZXJ0KGksIGopKSB7CgkJCQlhbnMgPSBpNjQoYW5zKSAqIHdheXNbdmVydChpLCBqKV0gJSBNT0Q7CgkJCX0KCQl9Cgl9Cgljb3V0IDw8IGFucyA8PCAnXG4nOwoKCXJldHVybiAwOwp9Cg==