#include #include #define rep(i,n) for (int i = 0; i < int(n); ++i) using namespace std; using P = pair; using mint = atcoder::modint998244353; void solve(){ int h, w, k; cin >> h >> w >> k; int g = __gcd(h,w); if (k == 0){ mint ans = mint(2).pow(h) + mint(2).pow(w) + mint(2).pow(g+2); if (g % 2 == 1){ ans -= 8; } else { ans += mint(2).pow(h+w+1); if (g % 4 == 0){ ans += 32; } else { ans -= 16; } } cout << ans.val() << endl; return ; } vector xs(k), ys(k), ds(k); rep(i,k){ cin >> xs[i] >> ys[i]; char c; cin >> c; ds[i] = (c == 'U' ? 0 : c == 'L' ? 1 : c == 'D' ? 2 : 3); } auto number_of_sort = [&](map &mp){ vector dcnt(4,0); for (auto p : mp) dcnt[p.second]++; int res = 0; rep(i,4) if (dcnt[i] > 0) res++; return res; }; auto Case1 = [&](){ vector dcnt(4,0); rep(i,k) dcnt[ds[i]]++; int ver = dcnt[0] + dcnt[2], hor = dcnt[1] + dcnt[3]; if (ver > 0 && hor > 0) return mint(0); if (ver > 0){ map mx; rep(i,k){ if (mx.find(xs[i]) == mx.end()){ mx[xs[i]] = ds[i]; } else if (mx[xs[i]] != ds[i]){ return mint(0); } } int siz = mx.size(); return mint(2).pow(h-siz); } if (hor > 0){ map my; rep(i,k){ if (my.find(ys[i]) == my.end()){ my[ys[i]] = ds[i]; } else if (my[ys[i]] != ds[i]){ return mint(0); } } int siz = my.size(); return mint(2).pow(w-siz); } return mint(0); }; auto Case2 = [&](){ if (g % 2 == 1) return mint(0); vector dcnt0(4,0), dcnt1(4,0); rep(i,k){ ((xs[i]+ys[i])%2 == 0 ? dcnt0 : dcnt1)[ds[i]]++; } int ver0 = dcnt0[0] + dcnt0[2], hor0 = dcnt0[1] + dcnt0[3]; int ver1 = dcnt1[0] + dcnt1[2], hor1 = dcnt1[1] + dcnt1[3]; if (ver0 > 0 && hor0 > 0) return mint(0); if (ver1 > 0 && hor1 > 0) return mint(0); if (ver0 > 0 && ver1 > 0) return mint(0); if (hor0 > 0 && hor1 > 0) return mint(0); if (ver0 > 0 || hor1 > 0){ map mx, my; rep(i,k){ if ((xs[i]+ys[i]) % 2 == 0){ if (mx.find(xs[i]) == mx.end()){ mx[xs[i]] = ds[i]; } else if (mx[xs[i]] != ds[i]){ return mint(0); } } else { if (my.find(ys[i]) == my.end()){ my[ys[i]] = ds[i]; } else if (my[ys[i]] != ds[i]){ return mint(0); } } } int sizx = mx.size(), sizy = my.size(); mint res = mint(2).pow(h-sizx+w-sizy); res -= (2 - number_of_sort(mx)) * (2 - number_of_sort(my)); return res; } if (hor0 > 0 || ver1 > 0){ map mx, my; rep(i,k){ if ((xs[i]+ys[i]) % 2 == 1){ if (mx.find(xs[i]) == mx.end()){ mx[xs[i]] = ds[i]; } else if (mx[xs[i]] != ds[i]){ return mint(0); } } else { if (my.find(ys[i]) == my.end()){ my[ys[i]] = ds[i]; } else if (my[ys[i]] != ds[i]){ return mint(0); } } } int sizx = mx.size(), sizy = my.size(); mint res = mint(2).pow(h-sizx+w-sizy); res -= (2 - number_of_sort(mx)) * (2 - number_of_sort(my)); return res; } return mint(0); }; mint ans = Case1() + Case2(); bool modgok = true; map mgok; rep(i,k){ xs[i] %= g, ys[i] %= g; if (mgok.find(P(xs[i],ys[i])) == mgok.end()){ mgok[P(xs[i],ys[i])] = ds[i]; } else if (mgok[P(xs[i],ys[i])] != ds[i]){ modgok = false; } } if (!modgok){ cout << ans.val() << endl; return ; } auto mod = [&](int xy){ return (xy%g+g)%g; }; auto Case3 = [&](){ vector dcnt(4,0); rep(i,k) dcnt[ds[i]]++; int nonzero = 0, id1 = -1, id2 = -1; rep(i,4){ if (dcnt[i] > 0){ nonzero++; if (id1 == -1) id1 = i; else if (id2 == -1) id2 = i; } } if (nonzero >= 3) return mint(0); if (id2 != -1){ if ((id1 != 0 || id2 != 1) && (id1 != 2 || id2 != 3)){ return mint(0); } } map xmy; rep(i,k){ int ixmy = mod(xs[i]-ys[i]); if (xmy.find(ixmy) == xmy.end()){ xmy[ixmy] = ds[i]; } else if (xmy[ixmy] != ds[i]){ return mint(0); } } int siz = xmy.size(); return mint(2).pow(g-siz) - 2 + nonzero; }; auto Case4 = [&](){ vector dcnt(4,0); rep(i,k) dcnt[ds[i]]++; int nonzero = 0, id1 = -1, id2 = -1; rep(i,4){ if (dcnt[i] > 0){ nonzero++; if (id1 == -1) id1 = i; else if (id2 == -1) id2 = i; } } if (nonzero >= 3) return mint(0); if (id2 != -1){ if ((id1 != 0 || id2 != 3) && (id1 != 1 || id2 != 2)){ return mint(0); } } map xpy; rep(i,k){ int ixpy = mod(xs[i]+ys[i]); if (xpy.find(ixpy) == xpy.end()){ xpy[ixpy] = ds[i]; } else if (xpy[ixpy] != ds[i]){ return mint(0); } } int siz = xpy.size(); return mint(2).pow(g-siz) - 2 + nonzero; }; ans += Case3() + Case4(); if (g % 4 != 0){ cout << ans.val() << endl; return ; } auto Case5 = [&](){ vector> m4(4,vector(4,-1)); rep(i,k){ xs[i] %= 4, ys[i] %= 4; if (m4[xs[i]][ys[i]] == -1){ m4[xs[i]][ys[i]] = ds[i]; } else if (m4[xs[i]][ys[i]] != ds[i]){ return mint(0); } } vector> tmp1 = { {0, 3, 1, 3}, {1, 3, 1, 2}, {1, 3, 0, 3}, {1, 2, 1, 3} }; vector> tmp2 = { {1, 0, 1, 3}, {1, 3, 2, 3}, {1, 3, 1, 0}, {2, 3, 1, 3} }; vector> tmp3 = { {0, 0, 0, 3}, {1, 2, 2, 2}, {0, 3, 0, 0}, {2, 2, 1, 2} }; vector> tmp4 = { {1, 0, 0, 0}, {2, 2, 2, 3}, {0, 0, 1, 0}, {2, 3, 2, 2} }; vector> tmp5 = { {0, 0, 1, 3}, {1, 3, 2, 2}, {1, 3, 0, 0}, {2, 2, 1, 3} }; vector> tmp6 = { {1, 0, 0, 3}, {1, 2, 2, 3}, {0, 3, 1, 0}, {2, 3, 1, 2} }; vector>> tmp = {tmp1,tmp2,tmp3,tmp4,tmp5,tmp6}; auto match = [&](vector> &test, int ex, int ey){ rep(x,4) rep(y,4){ if (m4[x][y] == -1 || m4[x][y] == test[(x+ex)%4][(y+ey)%4]){ continue; } return false; } return true; }; mint res = 0; rep(i,6) rep(ex,4) rep(ey,2) if (match(tmp[i],ex,ey)) res++; return res; }; ans += Case5(); cout << ans.val() << endl; } int main(){ cin.tie(0); ios::sync_with_stdio(0); int t = 1; cin >> t; while(t--) solve(); }