// ?????¬???????????¬??????

#include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
using namespace std;

#define rep(i,a,n) for(int (i)=(a); (i)<(n); (i)++)
#define repq(i,a,n) for(int (i)=(a); (i)<=(n); (i)++)
#define repr(i,a,n) for(int (i)=(a); (i)>=(n); (i)--)
#define int long long int

template<typename T> void chmax(T &a, T b) {a = max(a, b);}
template<typename T> void chmin(T &a, T b) {a = min(a, b);}
template<typename T> void chadd(T &a, T b) {a = a + b;}

typedef pair<int, int> pii;
typedef long long ll;

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
constexpr ll INF = 1001001001001001LL;
constexpr ll MOD = 100000LL;

char board[30][30];
int dp[2][1 << 19][2];

ll mod_pow(ll x, ll n) {
    if(n == 0) return 1;
    ll res = mod_pow((x * x) % MOD, n / 2);
    if(n & 1) res = (res * x) % MOD;
    return res;
}

// generate binary string (not less than k-digit)
// ????????????????????§?????? (????????????????????? reverse ?????????????????¢??????)
string to_binString(int n, int k) {
    string ret = "";
    while(n) ret += ('0' + (n&1)), n >>= 1;
    while(ret.length() < k) ret += '0';
    // reverse(ret.begin(), ret.end());
    return ret;
}

signed main() {
    int H, W; cin >> H >> W;
    int que_cnt = 0;
    rep(i,0,H) rep(j,0,W) {
        cin >> board[i][j];
        if(board[i][j] == '?') que_cnt++;
    }

    dp[0][0][0] = 1;
    int base = mod_pow(3, que_cnt);
    rep(i,0,H) rep(j,0,W) {
        int mo = (i*W+j) % 2, nbit;
        rep(bit,0,1<<(W-1)) rep(k,0,2) {
            if(!dp[mo][bit][k]) continue;
            // ??????????????\???????????????????????????????????? (??±???)

            if(board[i][j] == 'J' || board[i][j] == '?') {
                // J
                nbit = bit;
                if(j != W-1) nbit >>= 1;
                (dp[mo^1][nbit][1] += dp[mo][bit][k]) %= MOD;
            }

            if(board[i][j] == 'O' || board[i][j] == '?') {
                // O
                // ????????????????????§?????????????????´?????? 'J' ????????°???????????? bit ??? 1 ?????????
                nbit = bit;
                if(k == 1 && j != 0) nbit |= (1 << (W-2));
                if(j != W-1) nbit >>= 1;
                (dp[mo^1][nbit][0] += dp[mo][bit][k]) %= MOD;
            }

            if(board[i][j] == 'I' || board[i][j] == '?') {
                // I (j ?????????????????????????????\?????§????????????????????? 0 ?????¨??????????????????)
                if(j == W-1 || !(bit & 1)) {
                    nbit = bit;
                    if(j != W-1) nbit >>= 1;
                    (dp[mo^1][nbit][0] += dp[mo][bit][k]) %= MOD;
                }
            }
        }
        memset(dp[mo], 0, sizeof(dp[mo]));
    }
    int sum = 0;
    int mo = ((H-1)*W + (W-1) + 1) % 2;
    rep(i,0,1<<(W-1)) rep(j,0,2) (sum += dp[mo][i][j]) %= MOD;
    cout << (base - sum + MOD) % MOD << endl;
    return 0;
}

Measured memory_bytes: 19484