#include <fstream>
using namespace std;
ifstream f("barbar.in");
ofstream g("barbar.out");
int n,R,C,k,xf,yf,xp,yp,maxim;
int d[1011][1011];
int di[4]={-1,0,1,0};
int dj[4]={0,1,0,-1};
struct pozitii{
int i,j;
};
pozitii h[1011*1011*3],c[1011*1011*4];
void update(){
int p,c;
pozitii aux;
c=k;
p=c/2;
while(p>0 && d[h[p].i][h[p].j]>d[h[c].i][h[c].j]){
aux=h[p],h[p]=h[c],h[c]=aux;
c=p,p/=2;
}
}
void stergere(){
int p=1,c=2;
pozitii aux=h[1];
h[1]=h[k],h[k]=aux;
k--;
if(c+1<=k && d[h[c].i][h[c].j]>d[h[c+1].i][h[c+1].j]) c++;
/* while(c<=k && d[h[p].i][h[p].j]>d[h[c].i][h[c].j]){
aux=h[p],h[p]=h[c],h[c]=aux;
p=c,c*=2;
if(c+1<=k && d[h[c].i][h[c].j]>d[h[c+1].i][h[c+1].j]) c++;
}*/
}
bool ver(int dist){
register int i,j,p,u,dr,iv,jv;
bool viz[1011][1011];
p=u=1;
c[p].i=xp,c[p].j=yp;
if(d[xp][yp]<dist)
return false;
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,x,y,dr,iv,jv;
char ch;
f>>R>>C;
for(i=1;i<=R;i++){
for(j=1;j<=C;j++){
f>>ch;
if(ch=='.')
d[i][j]=1011*1011*10;
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,h[++k].i=i,h[k].j=j;
}
}
int nr=0;
int minim;
do{
minim=d[h[1].i][h[1].j];
x=h[1].i,y=h[1].j;
stergere();
for(dr=0;dr<4;dr++){
iv=x+di[dr],jv=y+dj[dr];
if(iv>0 && jv>0 && iv<=R && jv<=C){
if(d[iv][jv]>minim+1)
d[iv][jv]=minim+1,h[++k].i=iv,h[k].j=jv,nr++,update();
else if(d[iv][jv]==-2 || d[iv][jv]==-3){
if(maxim<minim)
maxim=minim,nr++;
}
}
}
}while(nr<R*C);
int p=1,u=maxim,mij,sol;
while(p<=u){
mij=p+(u-p)/2;
if(ver(mij))
sol=mij,p=mij+1;
else
u=mij-1;
}
g<<sol;
/* for(i=1;i<=R;i++){
for(j=1;j<=C;j++)
g<<d[i][j]<<" ";
g<<"\n";
}*/
f.close();
g.close();
return 0;
}