#include <bits/stdc++.h>
using namespace std;
//#define cerr if (false) cerr
#define db(x) cerr << #x << "=" << x << endl
#define db2(x, y) cerr << #x << "=" << x << "," << #y << "=" << y << endl
#define db3(x, y, z) cerr << #x << "=" << x << "," << #y << "=" << y << "," << #z << "=" << z << endl
#define dbv(v) cerr << #v << "="; for (auto _x : v) cerr << _x << ", "; cerr << endl
#define dba(a, n) cerr << #a << "="; for (int _i = 0; _i < (n); ++_i) cerr << a[_i] << ", "; cerr << endl
template <typename A, typename B>
ostream& operator<<(ostream& os, const pair<A, B>& x) {
	return os << "(" << x.first << "," << x.second << ")";
}
typedef long long ll;
typedef long double ld;
const int MOD = 998244353;
struct Mint {
	int val;
	Mint() { val = 0; }
	Mint(const ll& x) {
		val = (-MOD <= x && x < MOD) ? x : x % MOD;
		if (val < 0) val += MOD;
	}
	friend bool operator==(const Mint& a, const Mint& b) { return a.val == b.val; }
	friend bool operator!=(const Mint& a, const Mint& b) { return !(a == b); }
	friend bool operator<(const Mint& a, const Mint& b) { return a.val < b.val; }
	Mint& operator+=(const Mint& m) { if ((val += m.val) >= MOD) val -= MOD; return *this; }
	Mint& operator-=(const Mint& m) { if ((val -= m.val) < 0) val += MOD; return *this; }
	Mint& operator*=(const Mint& m) { val = (ll)val * m.val % MOD; return *this; }
	friend Mint modex(Mint a, ll p) {
		assert(p >= 0);
		Mint ans = 1;
		for (; p; p >>= 1, a *= a) if (p & 1) ans *= a;
		return ans;
	}
	Mint& operator/=(const Mint& m) { return *this *= modex(m, MOD - 2); }
	Mint& operator++() { return *this += 1; }
	Mint& operator--() { return *this -= 1; }
	Mint operator++(int) { Mint result(*this); *this += 1; return result; }
	Mint operator--(int) { Mint result(*this); *this -= 1; return result; }
	Mint operator-() const { return Mint(-val); }
	friend Mint operator+(Mint a, const Mint& b) { return a += b; }
	friend Mint operator-(Mint a, const Mint& b) { return a -= b; }
	friend Mint operator*(Mint a, const Mint& b) { return a *= b; }
	friend Mint operator/(Mint a, const Mint& b) { return a /= b; }
	friend ostream& operator<<(ostream& os, const Mint& x) { return os << x.val; }
};
const int MAXN = 15;
Mint dp[MAXN][MAXN][2][3];
Mint binom[MAXN][MAXN], p2[MAXN], val[MAXN][MAXN];
char G[MAXN][MAXN];
int main() {
	p2[0] = 1;
	for (int i = 1; i < MAXN; ++i) p2[i] = p2[i - 1] * 2;
	for (int i = 0; i < MAXN; ++i)
		for (int j = 0; j <= i; ++j)
			if (!j || j == i) binom[i][j] = 1;
			else binom[i][j] = binom[i - 1][j - 1] + binom[i - 1][j];
	int H, W;
	scanf("%d%d", &H, &W);
	for (int i = 0; i < H; ++i) scanf("%s", G[i]);
	auto calc = [&](bool mustEndWithRow, bool mustEndWithCol) {
		memset(dp, 0, sizeof(dp));
		dp[0][0][0][1] = 1;
		for (int r = 0; r <= H; ++r)
			for (int c = 0; c <= W; ++c) {
				if (!r && !c) continue;
				if (!r) {
					if (!mustEndWithRow) {
						dp[r][c][1][2] = p2[c] - 2;
						if (!mustEndWithCol) dp[r][c][1][1] = 2;
					}
					continue;
				}
				if (!c) {
					if (!mustEndWithCol) {
						dp[r][c][0][2] = p2[r] - 2;
						if (!mustEndWithRow) dp[r][c][0][1] = 2;
					}
					continue;
				}
				for (int rr = 1; rr <= r; ++rr) {
					dp[r][c][0][2] += (dp[r - rr][c][1][1] + dp[r - rr][c][1][2]) * binom[r][rr] * (p2[rr] - 2);
					dp[r][c][0][1] += dp[r - rr][c][1][1] * binom[r][rr];
				}
				for (int cc = 1; cc <= c; ++cc) {
					dp[r][c][1][2] += (dp[r][c - cc][0][1] + dp[r][c - cc][0][2]) * binom[c][cc] * (p2[cc] - 2);
					dp[r][c][1][1] += dp[r][c - cc][0][1] * binom[c][cc];
				}
			}
		for (int r = H; r >= 1; --r)
			for (int c = 1; c <= W; ++c) {
				dp[r][c][0][1] = 0;
				for (int rr = 1; rr <= r; ++rr) {
					dp[r][c][0][1] += (dp[r - rr][c][1][1] + dp[r - rr][c][1][2]) * binom[r][rr] * 2;
				}
			}
	};
	calc(false, false);
	for (int r = 0; r < H; ++r)
		for (int c = 0; c < W; ++c)
			val[r][c] = dp[r][c][0][2] + dp[r][c][1][2] + dp[r][c][1][1] + dp[r][c][0][1];
	calc(true, false);
	for (int c = 0; c < W; ++c)
		val[H][c] = dp[H][c][0][2] + dp[H][c][1][2] + dp[H][c][1][1] + dp[H][c][0][1];
	calc(false, true);
	for (int r = 0; r < H; ++r)
		val[r][W] = dp[r][W][0][2] + dp[r][W][1][2] + dp[r][W][1][1] + dp[r][W][0][1];
	Mint ans = 0;
	for (int i = 0; i < (1 << H); ++i) {
		for (int j = 0; j < (1 << W); ++j) {
			bool bad = false;
			for (int r = 0; r < H; ++r) {
				if (i & (1 << r)) continue;
				int has = 0;
				for (int c = 0; c < W; ++c) {
					if (j & (1 << c)) continue;
					has |= (G[r][c] == '.') + 1;
				}
				if (has && has < 3) bad = true;
			}
			for (int c = 0; c < W; ++c) {
				if (j & (1 << c)) continue;
				int has = 0;
				for (int r = 0; r < H; ++r) {
					if (i & (1 << r)) continue;
					has |= (G[r][c] == '.') + 1;
				}
				if (has && has < 3) bad = true;
			}
			if (bad) continue;
			int nr = __builtin_popcount(i);
			int nc = __builtin_popcount(j);
			if (nr == H && nc == W) continue;
			ans += val[nr][nc];
		}
	}
	ans += 2;
	printf("%d\n", ans.val);
}


Measured memory_bytes: 256