#include<iostream>
#include<map>
#include<set>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
typedef long long ll;
//1048576
const int N = 20;
const int K = 17712;
const ll mod = 100000;
//map<int,ll> M[N][N];
int mask;//(1<<n)-1
char m[N][N];
map<int,int> M;
int dp[20][20][K];

inline int getindex(int in){
  int index=M.size();
  if (M.find(in) == M.end())M[in]=index;
  return M[in];
}

ll solve(int r,int c,int now,int st){
  if (now == r*c)return 1;
  int ind=getindex(st);
  
  int y=now/c,x=now%c;
  int &ret=dp[y][x][ind];
  if (ret == mod+1){
    ll tmp=0;
    //J
    if (m[y][x] == '?' || m[y][x] == 'J'){
      int next=st;
      if (next%2 == 1)next=((next-1)<<1)|1;
      else next=(next<<1)|1;
      next=next&mask;
      tmp+=solve(r,c,now+1,next);
      tmp%=mod;
    }
    
    //O
    if (m[y][x] == '?' || m[y][x] == 'O'){
      if (st%2 == 1){//JO
	int next=st;
	next=(next<<1);
	next=next&mask;
	tmp+=solve(r,c,now+1,next);
	tmp%=mod;
      }else {
	int next=st;
	next=(next<<1);
	next=next&mask;
	tmp+=solve(r,c,now+1,next);
	tmp%=mod;
      }
    }
    
    //I
    if (m[y][x] == '?' || m[y][x] == 'I'){
      if (((1<<(c-1))&st) == 0 || x == c-1){
	int next=st;
	if (st%2 == 1)next=((next-1)<<1);
	else next=(next<<1);
	next=next&mask;
	tmp+=solve(r,c,now+1,next);
	tmp%=mod;
      }
    }
    ret=tmp;
  }
  return ret;
}


/*
ll solve(int r,int c,int now,int st){
  if (now == r*c)return 1;

  int y=now/c,x=now%c;
  if (M[y][x].find(st) != M[y][x].end()){
    return M[y][x][st];
  }

  ll ret=0;

  //J
  if (m[y][x] == '?' || m[y][x] == 'J'){
    int next=st;
    if (next%2 == 1)next=((next-1)<<1)|1;
    else next=(next<<1)|1;
    next=next&mask;
    ret+=solve(r,c,now+1,next);
    ret%=mod;
  }
  
  //O
  if (m[y][x] == '?' || m[y][x] == 'O'){
    if (st%2 == 1){//JO
      int next=st;
      next=(next<<1);
      next=next&mask;
      ret+=solve(r,c,now+1,next);
      ret%=mod;
    }else {
      int next=st;
      next=(next<<1);
      next=next&mask;
      ret+=solve(r,c,now+1,next);
      ret%=mod;
    }
  }

  //I
  if (m[y][x] == '?' || m[y][x] == 'I'){
    if (((1<<(c-1))&st) == 0 || x == c-1){
      int next=st;
      if (st%2 == 1)next=((next-1)<<1);
      else next=(next<<1);
      next=next&mask;
      ret+=solve(r,c,now+1,next);
      ret%=mod;
    }
  }
  return M[y][x][st]=(ret%mod);
}
*/

set<int>HOGE[21];
set<int>S;
void test(int now,char *in,int st){
  if (HOGE[now].find(st) != HOGE[now].end()){
    return;
  }
  HOGE[now].insert(st);
  if (now == 20){
    int tmp=st;
    /*
    st=0;
    for(int i=0;i<=1;i++){
      st=st<<1;
      if (in[i] == 'J' && in[i+1] == 'O')st=st|1;
    }
    if (in[2] == 'J')st=(st<<1)+1;
    else st=(st<<1);
    cout << in[0]<<in[1]<<in[2]<<" " <<st <<" " << tmp<< endl;
    */
    S.insert(tmp);
    return;
  }
  int tmp=st-1;
  in[now]='J';
  test(now+1,in,st%2==1?((tmp)<<1)|1:(st<<1)|1);
  in[now]='O';
  //test(now+1,in,st%2==1?(st<<1)      :((tmp)<<1));
  test(now+1,in,st<<1);
  in[now]='I';
  test(now+1,in,st%2==1?((tmp)<<1)  :(st<<1)  );
}

void test(){
  char in[20];
  test(0,in,0);
  cout << S.size() << endl;
}

void test2(){
  char out[3]={'J','O','I'};
  rep(i,3){
    rep(j,3){
      rep(k,3){
	cout << out[i]<<out[j]<<out[k]<<endl;
      }
    }
  }
}

void test3(){
  set<string> B;
  string a,b;
  while(cin>>a>>b){
    B.insert(b);
  }
  cout <<B.size() << endl;
}

main(){
  //test();
  //test2();
  //test3();
  //return 0;

  int r,c;
  while(cin>>r>>c && r){
    ll all=1;
    rep(i,r)cin>>m[i];
    rep(i,r)rep(j,c)if (m[i][j] == '?')all=(all*3)%mod;
    //rep(i,r)rep(j,c)M[i][j].clear();
    rep(k,K)rep(i,r)rep(j,c)dp[i][j][k]=mod+1;
    mask=(1<<c)-1;
    ll cans=solve(r,c,0,0);
    ll a=(all-cans+mod)%mod;
    cout << a << endl;
  }
  return 0;
}

Measured memory_bytes: 28000