#include <bits/stdc++.h>

using namespace std;

#define int long long
const int mod = 1e9 + 7;
const int N = 5e6;
int binpow[N];


signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    int h, w;
    cin >> h >> w;

    vector<string> s(h);

    for (int i = 0; i < h; i++)
        cin >> s[i];

    binpow[0] = 1;
    for (int i = 1; i <= h * w; i++) {
        binpow[i] = (binpow[i - 1] * 2) % mod;
    }

    vector<vector<pair<int, int> > > col(h, vector<pair<int, int>>(w, make_pair(-1, h))),
            row(h, vector<pair<int, int>>(w, make_pair(-1, w)));


    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            if (s[i][j] == '#') {
                row[i][j].first = j;
            } else if (j > 0) {
                row[i][j].first = row[i][j - 1].first;
            }
        }

        for (int j = w - 1; j >= 0; j--) {
            if (s[i][j] == '#') {
                row[i][j].second = j;
            } else if (j < w - 1) {
                row[i][j].second = row[i][j + 1].second;
            }
        }
    }

    int k = 0;

    for (int j = 0; j < w; j++) {
        for (int i = 0; i < h; i++) {
            k += s[i][j] == '.';
            if (s[i][j] == '#') {
                col[i][j].first = i;
            } else if (i > 0) {
                col[i][j].first = col[i - 1][j].first;
            }
        }

        for (int i = h - 1; i >= 0; i--) {
            if (s[i][j] == '#') {
                col[i][j].second = i;
            } else if (i < h - 1) {
                col[i][j].second = col[i + 1][j].second;
            }
        }
    }

    int ans = 0;

    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            if (s[i][j] == '#')
                continue;
            int p = col[i][j].second - col[i][j].first + row[i][j].second - row[i][j].first - 3;
            ans = (ans + (binpow[k] - binpow[k - p] + mod) % mod) % mod;
        }
    }

    cout << ans << '\n';

}



//~ while (clock()<=69*CLOCKS_PER_SEC)
//~ #pragma comment(linker, "/stack:200000000")
#ifndef LOCAL
#pragma GCC optimize("O3")
#endif
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define st first
#define nd second

using namespace __gnu_pbds;
using namespace std;
 
template <typename T>
using ordered_set =
	tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
 
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
	*this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
 
#define shandom_ruffle random_shuffle
 
using ll=long long;
using pii=pair<int,int>;
using pll=pair<ll,ll>;
using vi=vector<int>;
using vll=vector<ll>;

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout << fixed << setprecision(11);
	cerr << fixed << setprecision(6);

	int n, L;
	cin >> n >> L;

	map<int, vector<pii>> move_intvs;

	vi ai(n), bi(n);
	for (auto &x : ai) { cin >> x; }
	for (auto &x : bi) { cin >> x; }

	vector<bool> found(n);

	map<int, int> pos_start;
	for (int i = 0; i < n; ++i) {
		pos_start[i] = ai[i];
	}
	pos_start[-1] = 0;
	pos_start[n] = L + 1;

	map<int, int> M;
	M[L + 1 - n] = n;

	for (int i = 0; i < n; ++i) {
		found[i] = (ai[i] == bi[i]);
	}

	for (int i = n - 1; i >= 0; --i) {
		const int seek = bi[i] - i;
		debug() << imie(seek);
		auto iter = M.find(seek);
		if (iter == M.end()) { M[ai[i] - i] = i; continue; }
		found[i] = true;
		const int who = iter->nd;
		debug() << imie(i) << imie(who) << imie("R");
		if (pos_start[who] - pos_start[i] > 1) {
			move_intvs[who].emplace_back(i, who - 1);
		}

		M[ai[i] - i] = i;
	}

	M.clear();
	M[1] = -1;
	for (int i = 0; i < n; ++i) {
		const int seek = bi[i] - i;
		auto iter = M.find(seek);
		if (iter == M.end()) { M[ai[i] - i] = i; continue; }
		found[i] = true;
		const int who = iter->nd;
		debug() << imie(i) << imie(who) << imie("L");
		if (abs(pos_start[who] - pos_start[i]) > 1) {
			move_intvs[who].emplace_back(who + 1, i);
		}

		M[ai[i] - i] = i;
	}

	debug() << imie(found);

	if (count(ALL(found), false)) {
		cout << "-1\n";
		return 0;
	}

	ll ans = 0;

	for (auto &info : move_intvs) {
		debug() << imie(info.second);
		const int x = info.first;

		int L = x, R = x;

		for (auto &intv : info.second) {
			if (intv.second == x - 1) {
				L = min(L, intv.first);
			} else if (intv.first == x + 1) {
				R = max(R, intv.second);
			} else {
				assert(false);
			}
		}

		ans += R - L;
	}

	cout << ans << "\n";
	
}
