#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <cfloat>
#include <ctime>
#include <cassert>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <numeric>
#include <list>


using namespace std;

#ifdef _MSC_VER
#define __typeof__ decltype
template <class T> int __builtin_popcount(T n) { return n ? 1 + __builtin_popcount(n & (n - 1)) : 0; }
#endif

#define foreach(it, c) for (__typeof__((c).begin()) it=(c).begin(); it != (c).end(); ++it)
#define all(c) (c).begin(), (c).end()
#define rall(c) (c).rbegin(), (c).rend()
#define clear(arr, val) memset(arr, val, sizeof(arr))

#define rep(i, n) for (int i = 0; i < n; ++i)

template <class T> void max_swap(T& a, const T& b) { a = max(a, b); }
template <class T> void min_swap(T& a, const T& b) { a = min(a, b); }

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

const double EPS = 1e-8;
const double PI = acos(-1.0);
const int dx[] = { 0, 1, 0, -1 };
const int dy[] = { 1, 0, -1, 0 };


int res = 0;
int w, h;
char s[32][32];
char c[32][32];
void dfs(int X, int Y)
{
	if (X == 0 && Y == h)
	{
		bool ok = false;
		for (int y = 0; y < h - 1; ++y)
		{
			for (int x = 0; x < w - 1; ++x)
			{
				if (c[y][x] == 'J' && c[y][x + 1] == 'O' && c[y + 1][x] == 'I')
					ok = true;
			}
		}
		if (ok)
		{
			++res;
		}
		
		return;
	}

	static const char* joi = "JOI";
	for (int i = 0; i < 3; ++i)
	{
		if (s[Y][X] == '?' || joi[i] == s[Y][X])
		{
			c[Y][X] = joi[i];
			if (X < w - 1)
				dfs(X + 1, Y);
			else
				dfs(0, Y + 1);
		}
	}			
}

map<int, int> states;
bool used_j[32];
void make_states(int p)
{
	if (p == w)
	{
		int s = 0;
		for (int i = 0; i < w; ++i)
			s |= used_j[i] << i;
		int pos = states.size();
		states[s] = pos;
	}
	else
	{
		make_states(p + 1);
		if (p == 0 || !used_j[p - 1])
		{
			used_j[p] = true;
			make_states(p + 1);
			used_j[p] = false;
		}
	}
}
int main()
{
	cin >> h >> w;
	rep (i, h)
		cin >> s[i];
	make_states(0);

	const int mod = 100000;
	static int dp[401][17777];
	dp[0][0] = 1;
	for (int i = 0; i < w * h; ++i)
	{
		int x = i % w, y = i / w;
		foreach (it, states)
		{
			int S = it->first;
			int cur = dp[i][it->second];

			int T = ((S >> 1) << 2) & ((1 << w) - 1);
			int J = S & 1;

			if (s[y][x] == 'J' || s[y][x] == '?')
			{
				(dp[i + 1][states[T | (x < w - 1)]] += cur) %= mod;
			}

			if (s[y][x] == 'O' || s[y][x] == '?')
			{
				(dp[i + 1][states[T | (J ? (1 << 1) : 0)]] += cur) %= mod;
			}

			if (s[y][x] == 'I' || s[y][x] == '?')
			{
				if (!(S >> (w - 1) & 1))
					(dp[i + 1][states[T]] += cur) %= mod;
			}
		}
	}


	int hatena = 0;
	for (int i = 0; i < h; ++i)
		for (int j = 0; j < w; ++j)
			if (s[i][j] == '?')
				++hatena;
	int all_pattern = 1;
	for (int i = 0; i < hatena; ++i)
		(all_pattern *= 3) %= mod;

	int non_joi = 0;
	for (int i = 0; i < states.size(); ++i)
		(non_joi += dp[w * h][i]) %= mod;

	int res = (all_pattern - non_joi + mod) % mod;
	cout << res << endl;
	//cout << "all: " << all_pattern << endl;
	//cout << "non_joi: " << non_joi << endl;
}

Measured memory_bytes: 27000