#include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define RFOR(i, a, b) for(int i = (a) - 1; i >= (b); i--)
#define SZ(a) int(a.size())
#define ALL(a) a.begin(), a.end()
#define PB push_back
#define MP make_pair
#define F first
#define S second
typedef long long LL;
typedef vector<int> VI;
typedef vector<LL> VL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef double db;
const int mod = 998244353;
int add(int a, int b)
{
return a + b < mod ? a + b : a + b - mod;
}
void updAdd(int& a, int b)
{
a += b;
if (a >= mod)
a -= mod;
}
int sub(int a, int b)
{
return a - b >= 0 ? a - b : a - b + mod;
}
void updSub(int& a, int b)
{
a -= b;
if (a < 0)
a += mod;
}
int mult(int a, int b)
{
return (LL)a * b % mod;
}
int binpow(int a, LL n)
{
int res = 1;
while (n)
{
if (n & 1)
res = mult(res, a);
a = mult(a, a);
n /= 2;
}
return res;
}
template<typename T>
void updMin(T& a, T b)
{
a = min(a, b);
}
template<typename T>
void updMax(T& a, T b)
{
a = max(a, b);
}
struct DSU
{
int n;
VI p, sz;
DSU(int _n = 0)
{
n = _n;
p.resize(n);
iota(ALL(p), 0);
sz.assign(n, 1);
}
int find(int v)
{
if (v == p[v])
return v;
return p[v] = find(p[v]);
}
bool unite(int u, int v)
{
u = find(u);
v = find(v);
if (u == v)
return false;
if (sz[u] > sz[v])
swap(u, v);
p[u] = v;
sz[v] += sz[u];
return true;
}
};
const int N = 1 << 20;
vector<PII> g[N];
int col[N];
bool ok;
void addEdge(int u, int v, int c)
{
g[u].PB({v, c});
g[v].PB({u, c});
}
void dfs(int v)
{
for (auto [to, w] : g[v])
{
if (col[to] == -1)
{
col[to] = col[v] ^ w;
dfs(to);
}
ok &= col[to] == (col[v] ^ w);
}
}
void solve()
{
int h, w;
cin >> h >> w;
vector<string> s(h);
for (string& si : s)
cin >> si;
FOR(i, 0, h * w)
{
g[i].clear();
col[i] = -1;
}
ok = true;
FOR(i, 0, h)
{
int f = -1, prv = -1;
FOR(j, 0, w)
{
if (s[i][j] == 'A')
continue;
if (prv != -1)
{
addEdge(w * i + j, w * i + prv, (j - prv - 1) % 2);
}
prv = j;
if (f == -1)
f = j;
}
if (f != -1)
{
addEdge(w * i + prv, w * i + f, (w - prv + f - 1) % 2);
}
}
FOR(j, 0, w)
{
int f = -1, prv = -1;
FOR(i, 0, h)
{
if (s[i][j] == 'A')
continue;
if (prv != -1)
{
addEdge(w * i + j, w * prv + j, (i - prv - 1) % 2);
}
prv = i;
if (f == -1)
f = i;
}
if (f != -1)
{
addEdge(w * prv + j, w * f + j, (h - prv + f - 1) % 2);
}
}
FOR(i, 0, h * w)
{
if (col[i] == -1)
{
col[i] = 0;
dfs(i);
}
}
if (!ok)
{
cout << "0\n";
return;
}
DSU dsu(h + w);
FOR(i, 0, h)
{
FOR(j, 0, w)
{
if (s[i][j] == 'B')
{
dsu.unite(i, h + j);
}
}
}
int ans = 1;
FOR(i, 0, h + w)
{
if (dsu.find(i) == i)
{
ans = mult(ans, 2);
}
}
cout << ans << "\n";
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int t;
cin >> t;
while (t--)
solve();
return 0;
}