#include <bits/stdc++.h>
// #include <atcoder/all>
#define rep(i, a) for (int i = (int)0; i < (int)a; ++i)
#define rrep(i, a) for (int i = (int)a - 1; i >= 0; --i)
#define REP(i, a, b) for (int i = (int)a; i < (int)b; ++i)
#define RREP(i, a, b) for (int i = (int)a - 1; i >= b; --i)
#define pb push_back
#define eb emplace_back
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define popcount __builtin_popcount
using ll = long long;
constexpr ll mod = 1e9 + 7;
constexpr ll INF = 1LL << 60;

// #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")
template <class T>
inline bool chmin(T &a, T b)
{
	if (a > b)
	{
		a = b;
		return true;
	}
	return false;
}
template <class T>
inline bool chmax(T &a, T b)
{
	if (a < b)
	{
		a = b;
		return true;
	}
	return false;
}

template <typename T>
T mypow(T x, T n, const T &p = -1)
{ //x^nをmodで割った余り
	T ret = 1;
	while (n > 0)
	{
		if (n & 1)
		{
			if (p != -1)
				ret = (ret * x) % p;
			else
				ret *= x;
		}
		if (p != -1)
			x = (x * x) % p;
		else
			x *= x;
		n >>= 1;
	}
	return ret;
}

using namespace std;
// using namespace atcoder;

template< int mod >
struct ModInt {
  int x;

  ModInt() : x(0) {}

  ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}

  ModInt &operator+=(const ModInt &p) {
    if((x += p.x) >= mod) x -= mod;
    return *this;
  }

  ModInt &operator-=(const ModInt &p) {
    if((x += mod - p.x) >= mod) x -= mod;
    return *this;
  }

  ModInt &operator*=(const ModInt &p) {
    x = (int) (1LL * x * p.x % mod);
    return *this;
  }

  ModInt &operator/=(const ModInt &p) {
    *this *= p.inverse();
    return *this;
  }

  ModInt operator-() const { return ModInt(-x); }

  ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; }

  ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; }

  ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; }

  ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; }

  bool operator==(const ModInt &p) const { return x == p.x; }

  bool operator!=(const ModInt &p) const { return x != p.x; }

  ModInt inverse() const {
    int a = x, b = mod, u = 1, v = 0, t;
    while(b > 0) {
      t = a / b;
      swap(a -= t * b, b);
      swap(u -= t * v, v);
    }
    return ModInt(u);
  }

  ModInt pow(int64_t n) const {
    ModInt ret(1), mul(x);
    while(n > 0) {
      if(n & 1) ret *= mul;
      mul *= mul;
      n >>= 1;
    }
    return ret;
  }

  friend ostream &operator<<(ostream &os, const ModInt &p) {
    return os << p.x;
  }

  friend istream &operator>>(istream &is, ModInt &a) {
    int64_t t;
    is >> t;
    a = ModInt< mod >(t);
    return (is);
  }

  static int get_mod() { return mod; }
};

using modint = ModInt< mod >;


void solve()
{
	ll h,w,k;
	cin>>h>>w>>k;
	vector<vector<char>>s(h,vector<char>(w,'#'));
	rep(i,k){
		int a,b;
		char c;
		cin>>a>>b>>c;
		a--;b--;
		s[a][b]=c;
	}
	constexpr ll m=998244353;
	vector<vector<ModInt<m>>>dp(h+5,vector<ModInt<m>>(w+5));

	ModInt<m>mul=3;
	mul=mul.pow(h*w-k);
	dp[0][0]=mul;
	rep(i,h){
		rep(j,w){
			if(s[i][j]=='X'){
				dp[i+1][j]+=dp[i][j];
				dp[i][j+1]+=dp[i][j];
			}
			else if(s[i][j]=='R'){
				dp[i][j+1]+=dp[i][j];
			}
			else if(s[i][j]=='D'){
				dp[i+1][j]+=dp[i][j];
			}
			else{

				dp[i+1][j]+=dp[i][j]/3*2;
				dp[i][j+1]+=dp[i][j]/3*2;
			}
			
		}
	}
	

	ModInt<m>ans=dp[h-1][w-1];
	cout<<ans;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout << fixed << setprecision(15);
	solve();
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pdd;

#define lc u << 1
#define rc u << 1 | 1
#define mid (t[u].l + t[u].r) / 2
#define INF 0x3f3f3f3f
#define lowbit(x) x & (-x)
#define mem(a, b) memset(a , b , sizeof(a))
#define FOR(i, x, n) for(int i = x;i <= n; i++)

// const ll mod = 998244353;
// const ll mod = 1e9 + 7;
// const double eps = 1e-6;
// const double PI = acos(-1);
// const double R = 0.57721566490153286060651209;

const int N = 1e6 + 10;
ll t[N];

void modify(int x, int n) {
    while(x <= n) {
        t[x]++;
        x += lowbit(x);
    }
}

ll query(int x) {
    ll ans = 0;
    while(x) {
        ans += t[x];
        x -= lowbit(x);
    }
    return ans;
}

struct Point {
    int x, y;
    friend bool operator < (const Point &a,const Point &b){
        return a.x == b.x ? a.y < b.y : a.x < b.x;
    }
    friend bool operator == (const Point &a,const Point &b){
        return a.x == b.x && a.y == b.y;
    }
}p[N];

bool vis[N];

void solve() {
    int H, W, M;
    cin >> H >> W >> M;
    int upx = H + 1, upy = W + 1;
    for(int i = 1;i <= M; i++) {
        cin >> p[i].x >> p[i].y;
        if(p[i].x == 1) upy = min(upy, p[i].y);
        if(p[i].y == 1) upx = min(upx, p[i].x);
    }
    for(int i = upx + 1;i <= H; i++) {
        ++M;
        p[M].x = i; p[M].y = 1;
    }
    for(int j = upy + 1;j <= W; j++) {
        ++M;
        p[M].y = j; p[M].x = 1;
    }
    sort(p + 1, p + M + 1);
    M = unique(p + 1, p + M + 1) - (p + 1);

    int h = 1;
    ll ans = 0;
    for(int i = 1;i <= M; i++) {
        // 纵向扫描
        if(vis[p[i].y] == 0) {
            vis[p[i].y] = 1;
            modify(p[i].y, W);
        }

        // 横向扫描
        if(i == M || p[i + 1].x != p[i].x) {
            ans += query(W) - query(p[h].y - 1);
            h = i + 1;
        }
    }
    cout << (1ll * H * W - ans) << endl;
}

signed main() {
    ios_base::sync_with_stdio(false);
    //cin.tie(nullptr);
    //cout.tie(nullptr);
#ifdef FZT_ACM_LOCAL
//    int size=40<<20;
//    __asm__ ("movq %0,%%rsp\n"::"r"((char*)malloc(size)+size));
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    signed test_index_for_debug = 1;
    char acm_local_for_debug = 0;
    do {
        if (acm_local_for_debug == '$') exit(0);
        if (test_index_for_debug > 20)
            throw runtime_error("Check the stdin!!!");
        auto start_clock_for_debug = clock();
        solve();
        auto end_clock_for_debug = clock();
        cout << "Test " << test_index_for_debug << " successful" << endl;
        cerr << "Test " << test_index_for_debug++ << " Run Time: "
             << double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
        cout << "--------------------------------------------------" << endl;
    } while (cin >> acm_local_for_debug && cin.putback(acm_local_for_debug));
#else
    solve();
#endif
    return 0;
}

