#include<stdio.h>
#define INF 200
struct dragon {int x,y;}d[1000005];
int a1,b1,viz[1005][1005],xi,yi,xf,yf,mij,sol,min,max,m1,p,u,c[2][1000005],M[1005][1005],a,b,dr,i,n,j,di[1000005],D[2][5]={{0,1,0,-1},{1,0,-1,0}};
char m[1005][1005];
int drum(int k){
p=u=1;
c[0][p]=xf;
c[1][p]=yf;
viz[xf][yf]=k;
while(p<=u){
for(j=0;j<=3;j++){
a=c[0][p]+D[0][j];
b=c[1][p]+D[1][j];
if(viz[a][b]!=k&&M[a][b]>=k&&m[a][b]!='*'&&a>=1&&a<=n&&b>=1&&b<=m1){
u++;
c[0][u]=a;
c[1][u]=b;
viz[a][b]=k;
if(a==xi&&b==yi)
return 1;
}
}
p++;
}
return 0;
}
int main(){
FILE *f=fopen("barbar.in","r");
fscanf(f,"%d %d\n",&n,&m1);
for(i=1;i<=n;i++)
m[i][0]='0';
for(i=1;i<=n;i++){
for(j=1;j<=m1;j++){
fscanf(f,"%c",&m[i][j]);
if(m[i][j]=='D'){
dr++;
d[dr].x=i;
d[dr].y=j;
}
if(m[i][j]=='O'){
xf=i;
yf=j;
}
if(m[i][j]=='I'){
xi=i;
yi=j;
}
}
fscanf(f,"\n");
}
fclose(f);
for(i=1;i<=n;i++)
for(j=1;j<=m1;j++)
M[i][j]=INF;
max=-INF;
min=INF;
for(i=1;i<=dr;i++){
p=u=1;
c[0][p]=d[i].x;
c[1][p]=d[i].y;
M[c[0][p]][c[1][p]]=0;
di[p]=0;
while(p<=u){
for(j=0;j<=3;j++){
a=c[0][p]+D[0][j];
b=c[1][p]+D[1][j];
if(M[a][b]>di[p]+1&&m[a][b]!='*'&&a>=1&&a<=n&&b>=1&&b<=m1){
u++;
c[0][u]=a;
c[1][u]=b;
di[u]=di[p]+1;
M[a][b]=di[u];
}
}
p++;
}
}
for(i=1;i<=n;i++)
for(j=1;j<=m1;j++){
if(M[i][j]>max&&M[i][j]!=INF)
max=M[i][j];
}
a1=0;
b1=max;
sol=-1;
while(a1<=b1){
mij=(a1+b1)/2;
if(drum(mij)){
sol=mij;
a1=mij+1;
}
else
b1=mij-1;
}
FILE *g=fopen("barbar.out","w");
fprintf(g,"%d",sol);
fclose(g);
return 0;
}