/*input
3 3 5
2 3 D
1 3 D
2 1 D
1 2 X
3 1 R




*/
#include<bits/stdc++.h>
using namespace std;
#define ll long long int

const ll mod = 998244353,N = 5005;
ll H,W,K;
vector<vector<char>> mat(N,vector<char> (N,'.'));
vector<vector<ll>>  dp(N,vector<ll> (N,-1)),row(N,vector<ll> (N,0)),col(N,vector<ll> (N,0));
vector<ll> power3(N,0);


int main()
{
	cin>>H>>W>>K;
	for(int i=0;i<K;i++){
		ll x,y;cin>>x>>y;
		x--,y--;
		char c;cin>>c;
		mat[x][y] = c;
	}

	for(ll x=0;x<H;x++){
		for(ll y=W-1;y>=0;y--){
			row[x][y] = (mat[x][y]=='.') + (y!=W-1?row[x][y+1]:0);
		}
	}

	for(ll y=0;y<W;y++){
		for(ll x=H-1;x>=0;x--){
			col[x][y] = (mat[x][y]=='.') + (x!=H-1?col[x+1][y]:0);
		}
	}

	power3[0]=1;
	for(ll i =1;i<N;i++){
		power3[i] = (power3[i-1]*3)%mod;
	}


	for(ll x=H-1;x>=0;x--)
	{
		for(ll y=W-1;y>=0;y--)
		{

			if(x==H-1 && y==W-1) { dp[x][y] = ((mat[x][y]=='.')?3:1); continue; }

			ll ans = 0;
			if(mat[x][y]=='R'){
				if(y+1<W){
					ans = (ans + (dp[x][y+1] * power3[col[x][y]])%mod);
				} 
			}
			else if(mat[x][y]=='D'){
				if(x+1<H){
					ans = (ans + (dp[x+1][y] * power3[row[x][y]])%mod);
				} 
			}
			else if(mat[x][y]=='X'){
				if(y+1<W){
					ans = (ans + (dp[x][y+1] * power3[col[x][y]])%mod);
				} 
				if(x+1<H){
					ans = (ans + (dp[x+1][y] * power3[row[x][y]])%mod);
					if(ans>=mod) ans-=mod;
				} 
			}
			else{
				if(y+1<W){
					ll val = (dp[x][y+1] * power3[col[x+1][y]])%mod;
					val*=2;
					if(val>=mod) val-=mod;
					ans +=val; 
				} 
				if(x+1<H){
					ll val = 2*(dp[x+1][y] * power3[row[x][y+1]])%mod;
					if(val>=mod) val-=mod;
					ans+=val;
					if(ans>=mod) ans-=mod;
				} 
			}
			dp[x][y]=ans;
		}
	}
	cout<<dp[0][0]<<"\n";

	return 0;
}

#include<bits/stdc++.h>
using namespace std;

using ll = long long;

#define fi first
#define se second

const int N = 2e5 + 5;
const int INF = 2e9;
const ll LINF = 9e18;

struct query {
  int T, X, Y;
};

int n, m, q;
int a[N], b[N];
ll tree[4][N << 2];

// 0 = Sum_A, 1 = Sum_B, 2 = Freq_A, 3 = Freq_B

void update(int idx, int l, int r, int pos, ll val, int d) {
  if(l > pos || r < pos) return;
  if(l == r) {
    tree[d][idx] += val;
    return;
  }
  int mid = l + r >> 1;
  update(idx << 1, l, mid, pos, val, d);
  update(idx << 1 | 1, mid + 1, r, pos, val, d);
  tree[d][idx] = tree[d][idx << 1] + tree[d][idx << 1 | 1];
}

ll rangeSum(int idx, int l, int r, int from, int to, int d) {
  if(l > to || r < from) return 0;
  if(from <= l && r <= to) return tree[d][idx];
  int mid = l + r >> 1;
  return (
    rangeSum(idx << 1, l, mid, from, to, d) +
    rangeSum(idx << 1 | 1, mid + 1, r, from, to, d)
  );
}

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);

  cin >> n >> m >> q;
  vector<query> Q;
  set<int> distinct;
  distinct.insert(0);
  while(q--) {
    int t, x, y; cin >> t >> x >> y;
    Q.push_back({t, x, y});
    distinct.insert(y);
  }
  int cnt = 0;
  map<int, int> idx;
  for(int u : distinct) {
    idx[u] = ++cnt;
  }
  int s = distinct.size();

  update(1, 1, s, idx[0], n, 2);
  update(1, 1, s, idx[0], m, 3);

  ll ans = 0;
  for(query u : Q) {
    if(u.T == 1) {
      int prv = idx[a[u.X]];
      int nxt = idx[u.Y];
    
      ans -= rangeSum(1, 1, s, 1, prv, 3) * a[u.X];
      ans += rangeSum(1, 1, s, 1, prv, 1);
      ans -= rangeSum(1, 1, s, 1, nxt, 1);
      ans += rangeSum(1, 1, s, 1, nxt, 3) * u.Y;

      update(1, 1, s, prv, -a[u.X], 0);
      update(1, 1, s, nxt, u.Y, 0);
      update(1, 1, s, prv, -1, 2);
      update(1, 1, s, nxt, 1, 2);

      a[u.X] = u.Y;
    } else {
      int prv = idx[b[u.X]];
      int nxt = idx[u.Y];

      ans -= rangeSum(1, 1, s, 1, prv, 2) * b[u.X];
      ans += rangeSum(1, 1, s, 1, prv, 0);
      ans -= rangeSum(1, 1, s, 1, nxt, 0);
      ans += rangeSum(1, 1, s, 1, nxt, 2) * u.Y;

      update(1, 1, s, prv, -b[u.X], 1);
      update(1, 1, s, nxt, u.Y, 1);
      update(1, 1, s, prv, -1, 3);
      update(1, 1, s, nxt, 1, 3);

      b[u.X] = u.Y;
    }
    cout << ans << "\n";
  }
}