#include <iostream>
#include <assert.h>
#include <tuple>
#include <cstring>

using namespace std;

const int MAXN = 8;
const int MAXT = 19683;
const int MOD = 998244353;

const char* ch = "ICP";
const auto ICPC = make_tuple(0, 1, 2, 1);

int nr, nc, tmod = 1;
string g[MAXN];

int memo[MAXN][MAXN][MAXT];
int v[2*MAXN*MAXN];

int solve(int r, int c, int tail, int i) {
  if (c == nc) { c = 0; ++r; }
  if (r == nr) return 1;

  int& ans = memo[r][c][tail];

  if (ans == -1) {
    ans = 0;
    for (v[i] = 0; v[i] < 3; ++v[i]) {
      if (g[r][c] != '?' && ch[v[i]] != g[r][c]) continue;
      if (r != 0 && c != 0 && make_tuple(v[i-nc-1], v[i-nc], v[i-1], v[i]) == ICPC) continue;
      ans = (ans + solve(r, c + 1, (tail*3 + v[i])%tmod, i + 1))%MOD;
    }
  }

  assert(0 <= ans && ans < MOD);
  return ans;
}

int main() {
  cin >> nr >> nc;

  for (int j = 0; j <= nc; ++j) tmod *= 3;

  int pq = 1;
  for (int i = 0; i < nr; ++i) {
    cin >> g[i];
    for (auto x : g[i]) if (x == '?') pq = (3*(long long)pq)%MOD;
  }

  memset(memo, -1, sizeof(memo));

  cout << (pq - solve(0, 0, 0, 0) + MOD) % MOD << endl;
}
