#include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
//constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-12;

int N, M, K, H, W, L, R;
//long long int N, M, K, H, W, L, R;

int dp[3][1 << 19][2][2];

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

	cin >> H >> W;
	vector<string>s(H);
	for (auto &i : s)cin >> i;
	for (int i = 0; i < 1 << W; i++) {
		bool flag = true;
		int by = 1;
		for (int j = 0; j < W; j++) {
			if ((i >> j) & 1) {
				if (s.back()[j] == 'J' || s.back()[j] == 'O')flag = false;
			}
			else {
				if (s.back()[j] == 'I')flag = false;
				if (s.back()[j] == '?') {
					by *= 2;
					by %= 100000;
				}
			}
		}
		if (!flag)continue;
		if (s[H - 2][W - 1] == 'J' || s[H - 2][W - 1] == '?')dp[2][i&((1 << (W - 1)) - 1)][0][0] += by;
		if (s[H - 2][W - 1] == 'O' || s[H - 2][W - 1] == '?')dp[2][i&((1 << (W - 1)) - 1)][1][0] += by;
		if (s[H - 2][W - 1] == 'I' || s[H - 2][W - 1] == '?')dp[2][i&((1 << (W - 1)) - 1)][0][0] += by;
	}
	for (int h = H - 2; h >= 0; h--) {
		for (int w = W - 1; w >= 0; w--) {
			if (h + w == H + W - 3)continue;
			int cw = w & 1;
			if (w == W - 1)cw = 2;
			int befw = (w + 1) & 1;
			if (w + 1 == W - 1)befw = 2;
			if (w == W - 1)befw = 0;
			for (int i = 0; i < 1 << (W - 1); i++) {
				for (int j = 0; j < 2; j++) {
					for (int k = 0; k < 2; k++) {
						dp[cw][i][j][k] = 0;
						dp[befw][i][j][k] %= 100000;
					}
				}
			}
			for (int bit = 0; bit < 1 << (W - 1); bit++) {
				for (int o = 0; o < 2; o++) {
					for (int cnt = 0; cnt < 2; cnt++) {
						if (w == W - 1) {
							if (s[h][w] == 'J' || s[h][w] == '?') {
								int nxbit = bit;
								int nxo = 0;
								int nxcnt = cnt;
								dp[cw][nxbit][nxo][nxcnt] += dp[0][bit][o][cnt];
							}
							if (s[h][w] == 'O' || s[h][w] == '?') {
								int nxbit = bit;
								int nxo = 1;
								int nxcnt = cnt;
								dp[cw][nxbit][nxo][nxcnt] += dp[0][bit][o][cnt];
							}
							if (s[h][w] == 'I' || s[h][w] == '?') {
								int nxbit = bit;
								int nxo = 0;
								int nxcnt = cnt;
								dp[cw][nxbit][nxo][nxcnt] += dp[0][bit][o][cnt];
							}
						}
						else {
							if (s[h][w] == 'J' || s[h][w] == '?') {
								int nxbit = bit;
								if ((bit >> w) & 1)nxbit ^= 1 << w;
								int nxo = 0;
								int nxcnt = cnt || (o && ((bit >> w) & 1));
								dp[cw][nxbit][nxo][nxcnt] += dp[befw][bit][o][cnt];
							}
							if (s[h][w] == 'O' || s[h][w] == '?') {
								int nxbit = bit;
								if ((bit >> w) & 1)nxbit ^= 1 << w;
								int nxo = 1;
								int nxcnt = cnt;
								dp[cw][nxbit][nxo][nxcnt] += dp[befw][bit][o][cnt];
							}
							if (s[h][w] == 'I' || s[h][w] == '?') {
								int nxbit = bit;
								nxbit |= 1 << w;
								int nxo = 0;
								int nxcnt = cnt;
								dp[cw][nxbit][nxo][nxcnt] += dp[befw][bit][o][cnt];
							}
						}
					}
				}
			}
		}
	}
	int ans = 0;
	for (int i = 0; i < 1 << (W - 1); i++) {
		for (int j = 0; j < 2; j++) {
			ans += dp[0][i][j][1];
			ans %= 100000;
		}
	}
	cout << ans << endl;
}


Measured memory_bytes: 27724