import std.stdio;
import std.c.stdio;
import std.range;
import std.array;
import std.functional;
import std.algorithm;
import std.conv;
import std.container;
import std.math;
import std.numeric;
import std.string;
import std.c.string;
import std.regex;
import std.typecons;

bool get(int bit, int i) {
    return ((bit & (1 << i)) > 0);
}

int set(int bit, int i, bool x) {
    if (x) {
        return (bit | (1 << i));
    } else {
        return (bit & (~(1 << i)));
    }
}
 
void main() {
    int M, N; scanf("%d %d\n", &M, &N);
    string[] F;
    foreach (i; 0 .. M) { F ~= readln.chomp; }

    const MOD = 100000;

    auto pow3 = new int[401];
    pow3[0] = 1;
    foreach (i; 1 .. 401) {
        pow3[i] = (pow3[i - 1] * 3) % MOD;
    }

    int count(int y, int x) {
        int C = 0;
        foreach (j; x + 1 .. N) {
            if (F[y][j] == '?') C++;
        }
        foreach (i; y + 1 .. M) {
            foreach (j; 0 .. N) {
                if (F[i][j] == '?') C++;
            }
        }
        return pow3[C];
    }

    int raw_dfs(int y, int x, int bit, bool prev_j) {
        //writefln("(%d, %d), %b, %b", y, x, bit, prev_j);
        alias memoize!raw_dfs dfs;
        //alias raw_dfs dfs;
        if (y == M) return 0;
        if (x == N) {
            return dfs(y + 1, 0, bit, false);
        } else if (F[y][x] == 'J') {
            return dfs(y, x + 1, bit.set(x, false), true);
        } else if (F[y][x] == 'O') {
            bit = bit.set(x, false);
            if (prev_j) {
                bit = bit.set(x - 1, true);
            }
            return dfs(y, x + 1, bit, false);
        } else if (F[y][x] == 'I') {
            if (bit.get(x)) {
                return count(y, x);
            } else {
                return dfs(y, x + 1, bit.set(x, false), false);
            }
        } else {
            assert(F[y][x] == '?');
            int ret = 0;
            // try 'I'
            if (bit.get(x)) {
                ret += count(y, x);
            } else {
                ret += dfs(y, x + 1, bit.set(x, false), false);
            }
            ret %= MOD;
            bit = bit.set(x, false);
            // try 'J'
            ret += dfs(y, x + 1, bit, true);
            ret %= MOD;
            // try 'O'
            if (prev_j) {
                ret += dfs(y, x + 1, bit.set(x - 1, true), false);
            } else {
                ret += dfs(y, x + 1, bit, false);
            }
            ret %= MOD;
            return ret;
        }
    }

    writeln(raw_dfs(0, 0, 0, false));
}