#include <iostream>
#include <algorithm>
#include <utility>
#include <vector>
#define llint long long
#define inf 1e18
#define mod 998244353

using namespace std;
typedef pair<llint, llint> P;

llint h, w;
char c[15][15];
bool samex[10][1<<10], samey[10][1<<10];
llint pop[1<<10];
llint memo[15][15];
llint dp[15][15], dp2[15][15];

const int FACT_MAX = 105;
llint fact[FACT_MAX], fact_inv[FACT_MAX];

llint modpow(llint a, llint n)
{
	if(n == 0) return 1;
	if(n % 2){
		return ((a%mod) * (modpow(a, n-1)%mod)) % mod;
	}
	else{
		return modpow((a*a)%mod, n/2) % mod;
	}
}

void make_fact()
{
	llint val = 1;
	fact[0] = 1;
	for(int i = 1; i < FACT_MAX; i++){
		val *= i;
		val %= mod;
		fact[i] = val;
	}
	fact_inv[FACT_MAX-1] = modpow(fact[FACT_MAX-1], mod-2);
	for(int i = FACT_MAX-2; i >= 0; i--){
		fact_inv[i] = fact_inv[i+1] * (i+1) % mod;
	}
}

llint comb(llint n, llint k)
{
	llint ret = 1;
	ret *= fact[n];
	ret *= fact_inv[k], ret %= mod;
	ret *= fact_inv[n-k], ret %= mod;
	return ret;
}

llint dfs(llint w, llint h)
{
	if(w == 0 || h == 0) return 1;
	if(memo[w][h] != -1) return memo[w][h];
	
	llint ret = 1;
	for(int i = 1; i <= w-1; i++){
		for(int j = 1; j <= h; j++){
			ret += dfs(i, h-j) * comb(w, i) % mod * comb(h, j) % mod, ret %= mod;
		}
	}
	return memo[w][h] = ret;
}

int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	cin >> h >> w;
	for(int y = 0; y < h; y++){
		for(int x = 0; x < w; x++){
			cin >> c[x][y];
		}
	}
	
	make_fact();
	for(int i = 1; i < (1<<10); i++) pop[i] = pop[i&(i-1)] + 1;
	
	llint W = 1<<w, H = 1<<h;
	for(int y = 0; y < h; y++){
		for(int i = 0; i < W; i++){
			char p = '*';
			samex[y][i] = true;
			for(int x = 0; x < w; x++){
				if(i & (1<<x)){
					if(p == '*') p = c[x][y];
					else if(p != c[x][y]) samex[y][i] = false;
				}
			}
		}
		samex[y][0] = false;
	}
	for(int x = 0; x < w; x++){
		for(int i = 0; i < H; i++){
			char p = '*';
			samey[x][i] = true;
			for(int y = 0; y < h; y++){
				if(i & (1<<y)){
					if(p == '*') p = c[x][y];
					else if(p != c[x][y]) samey[x][i] = false;
				}
			}
		}
		samex[x][0] = false;
	}
	
	for(int x = 0; x <= w; x++){
		for(int y = 0; y <= h; y++){
			memo[x][y] = -1;
		}
	}
	for(int x = 0; x <= w; x++){
		for(int y = 0; y <= h; y++){
			for(int i = 0; i <= y; i++){
				dp[x][y] += dfs(x, y-i) * comb(y, i) % mod;
				dp[x][y] %= mod;
			}
			if(x == 0) dp[x][y] = 1;
		}
	}

	for(int i = 0; i <= w; i++){
		for(int j = 0; j <= h; j++){
			if(i == 0){
				dp2[i][j] = 1<<j;
				continue;
			}
			if(j == 0){
				dp2[i][j] = 1<<i;
				continue;
			}
			for(int k = 0; k <= i; k++){
				for(int l = 0; l <= j; l++){
					dp2[i][j] += comb(i, k) * comb(j, l) % mod * dp[k][l] % mod * dp[i-k][j-l] % mod;
					dp2[i][j] %= mod;
				}
			}
		}
	}
	
	llint ans = dp[w][h];
	for(int i = 0; i < W; i++){
		for(int j = 0; j < H; j++){
			if(pop[i] == w || pop[j] == h) continue;
			
			bool flag = true;
			for(int y = 0; y < h; y++){
				if(j & (1<<y)) continue;
				if(samex[y][W-1-i]) flag = false;
			}
			for(int x = 0; x < w; x++){
				if(i & (1<<x)) continue;
				if(samey[x][H-1-j]) flag = false;
			}
			if(!flag) continue;
			
			ans += dp2[pop[i]][pop[j]], ans %= mod;
		}
	}
	cout << ans << endl;
	
	
	return 0;
}

Measured memory_bytes: 256