#include <fstream>
#include <string.h>
using namespace std;
ifstream f("barbar.in");
ofstream g("barbar.out");
int R,C,d[1011][1011],xp,yp,xf,yf;
int di[4]={-1,0,1,0};
int dj[4]={0,1,0,-1};
int viz[1011][1011];
struct coada{
int i;
int j;
};
coada c[1011*1011*2];
bool ver(int dist){
register int i,iv,jv,p,u,dr;
// bool viz[1011][1011];
for(i=1;i<=R;i++)
memset(viz[i],0,sizeof(viz));
p=u=1;
c[p].i=xp,c[p].j=yp;
while(p<=u){
for(dr=0;dr<4;dr++){
iv=c[p].i+di[dr],jv=c[p].j+dj[dr];
if(iv>0 && jv>0 && jv<=C && iv<=R && !viz[iv][jv]){
if(d[iv][jv]>=dist){
c[++u].i=iv,c[u].j=jv;
viz[iv][jv]=true;
}
else if(d[iv][jv]==-3)
return true;
}
}
p++;
}
return false;
}
int main(void){
register int i,j,p,u=0,dr,iv,jv,LIM=1011*1011*3,maxim,mid,sol;
char ch;
f>>R>>C;
for(i=1;i<=R;i++){
for(j=1;j<=C;j++){
f>>ch;
if(ch=='.')
d[i][j]=LIM;
else if(ch=='*')
d[i][j]=-1;
else if(ch=='I')
d[i][j]=-2,xp=i,yp=j;
else if(ch=='O')
d[i][j]=-3,xf=i,yf=j;
else
d[i][j]=0,c[++u].i=i,c[u].j=j;
}
}
p=1,maxim=0;
while(p<=u){
for(dr=0;dr<4;dr++){
iv=c[p].i+di[dr],jv=c[p].j+dj[dr];
if(iv>0 && jv>0 && jv<=C && iv<=R && d[iv][jv]==LIM){
c[++u].i=iv,c[u].j=jv;
d[iv][jv]=d[c[p].i][c[p].j]+1;
if(maxim<d[iv][jv])
maxim=d[iv][jv];
}
}
p++;
}
p=1,u=maxim;
while(p<=u){
mid=p+(u-p)/2;
if(ver(mid))
sol=mid,p=mid+1;
else
u=mid-1;
}
g<<sol;
f.close();
g.close();
return 0;
}