#include <bits/stdc++.h>
// #include <atcoder/all>
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define srep(i, s, t) for (int i = s; i < t; ++i)
#define drep(i, n) for (int i = (n)-1; i >= 0; --i)
using namespace std;
// using namespace atcoder;
typedef long long int ll;
typedef pair<int, int> P;
#define MAX_N 200005
const ll PERFECT = 100000000;
static uint32_t randxor() {
    static uint32_t x = 123456789;
    static uint32_t y = 362436069;
    static uint32_t z = 521288629;
    static uint32_t w = 88675123;
    uint32_t t;

    t        = x ^ (x << 11);
    x        = y;
    y        = z;
    z        = w;
    return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
}

// 0以上1未満の小数をとる乱数
static double rand01() { return (randxor() + 0.5) * (1.0 / UINT_MAX); }

int n, m;
string s[1000];
vector<int> a[1000];
int b[1000] = {};
int ans[20][20];
ll ma;

ll calc() {
    int cnt = 0;
    rep(k, m) {
        int ok = 0;
        rep(i, n) {
            rep(j, n) {
                ok = 1;
                rep(l, b[k]) {
                    if (ans[i][(j + l) % n] != a[k][l]) {
                        ok = 0;
                        break;
                    }
                }
                if (ok) break;
                ok = 1;
                rep(l, b[k]) {
                    if (ans[(i + l) % n][j] != a[k][l]) {
                        ok = 0;
                        break;
                    }
                }
                if (ok) break;
            }
            if (ok) break;
        }
        cnt += ok;
    }
    ll res = 0;
    if (cnt < m) {
        res = PERFECT * cnt / m;
    } else {
        int cnt2 = 0;
        rep(i, n) {
            rep(j, n) {
                if (ans[i][j] == 0) cnt2++;
            }
        }
        res = PERFECT * 2 * n * n / (2 * n * n - cnt2);
    }
    return res;
}

int main() {
    srand((unsigned)time(NULL));
    while (rand() % 100) randxor();

    string fileNameIfs = "in\\0000.txt";
    ifstream ifs(fileNameIfs.c_str());
    if (!ifs.is_open()) {  // 標準入力する
        cin >> n >> m;

        rep(i, m) cin >> s[i];

        rep(i, m) {
            b[i] = s[i].size();
            rep(j, b[i]) { a[i].push_back(s[i][j] - 'A' + 1); }
        }
    } else {  // ファイル入力する
        ifs >> n >> m;

        rep(i, m) ifs >> s[i];

        rep(i, m) {
            b[i] = s[i].size();
            rep(j, b[i]) { a[i].push_back(s[i][j] - 'A' + 1); }
        }
    }

    rep(i, 20) {
        rep(j, 20) { ans[i][j] = randxor() % 8 + 1; }
    }

    clock_t start, end;
    start = clock();

    ma = calc();

    int loop = 0;
    while (true) {
        loop++;
        int x   = randxor() % n;
        int y   = randxor() % n;
        int val = randxor() % 9;

        int keep  = ans[x][y];
        ans[x][y] = val;

        ll tmp = calc();
        if (tmp >= ma) {
            ma = tmp;
        } else {
            ans[x][y] = keep;
        }

        end = clock();
        if ((double)(end - start) / CLOCKS_PER_SEC > 2.9) break;
    }

    // cout << loop << endl;
    // cout << calc() << endl;

    rep(i, n) {
        rep(j, n) {
            if (ans[i][j] == 0) {
                cout << '.';
            } else {
                cout << (char)(ans[i][j] + 'A' - 1);
            }
        }
        cout << endl;
    }
    return 0;
}

#include <bits/stdc++.h>
using namespace std;

const int mod = 1e9 + 7;
int n, m, ops[2000][2000][4];
string s[2000];

int modpow(int a, int b){
	if(!b) return 1;
	long long res = modpow(a, b / 2);
	res = (res * res) % mod;
	if(b % 2) res = (res * a) % mod;
	return res;
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cin >> n >> m;
	long long open = 0;
	for(int i = 0; i < n; i++){
		cin >> s[i];
		for(char j : s[i])
			if(j == '.') open++;
	}
	//left
	for(int i = 0; i < n; i++){
		int cur = 0;
		for(int j = 0; j < m; j++)
			if(s[i][j] == '#') cur = 0;
			else ops[i][j][0] = cur++;
	}
	//right
	for(int i = 0; i < n; i++){
		int cur = 0;
		for(int j = m - 1; j >= 0; j--)
			if(s[i][j] == '#') cur = 0;
			else ops[i][j][2] = cur++;
	}
	//up
	for(int i = 0; i < m; i++){
		int cur = 0;
		for(int j = 0; j < n; j++)
			if(s[j][i] == '#') cur = 0;
			else ops[j][i][1] = cur++;
	}
	//down
	for(int i = 0; i < m; i++){
		int cur = 0;
		for(int j = n - 1; j >= 0; j--)
			if(s[j][i] == '#') cur = 0;
			else ops[j][i][3] = cur++;
	}
	long long ans = (open * modpow(2, open)) % mod;
	for(int i = 0; i < n; i++)
		for(int j = 0; j < m; j++){
			if(s[i][j] == '#') continue;
			int rem = modpow(2, open - ops[i][j][0] - ops[i][j][1] - ops[i][j][2] - ops[i][j][3] - 1);
			ans = ((ans - rem) % mod + mod) % mod;
		}
	cout << ans << '\n';
	return 0;
}

/*
find what scenarios where none activated
*/