#include<stdio.h>
#include<string.h>
#define INF 2000000
#define MAXN 1005
FILE *f=fopen("barbar.in","r"), *g=fopen("barbar.out","w");
struct Coordonate{ int x, y; };
int N, M, p=1, u=0;
int A[MAXN][MAXN], viz[MAXN][MAXN];
int Dx[5]={0,-1,0,1,0}, Dy[5]={0,0,1,0,-1};
Coordonate ST, FN, Q[MAXN*MAXN], w;
// A[][] = INF liber / 0 dragon / -1 obstacol
void Citire(){
int i, j, c;
char s[MAXN];
fscanf(f,"%d %d\n",&N,&M);
for(i=1;i<=N;i++){
fscanf(f,"%s",s);
for(j=1;j<=M;j++){
c = s[j-1];
if( c == '.' )
A[i][j] = INF;
else if( c == 'D' ){
A[i][j] = 0;
w.x = i;
w.y = j;
Q[++u] = w;
}
else if( c == '*' )
A[i][j] = -1;
else if( c == 'I' ){
ST.x = i;
ST.y = j;
A[i][j] = INF;
}
else if( c == 'O' ){
FN.x = i;
FN.y = j;
A[i][j] = INF;
}
}
}
for(i=0;i<=N+1;i++){ A[i][0] = -1; A[i][M+1] = -1; } // Bordare
for(j=0;j<=M+1;j++){ A[0][j] = -1; A[N+1][j] = -1; }
/*
for(int i=0;i<=N+1;i++){
for(int j=0;j<=M+1;j++){
if(A[i][j]==-1)
fprintf(g,"- ");
else fprintf(g,"%d ",A[i][j]);
}
fprintf(g,"\n");
}
*/
}
void Preprocesare(){
int k, I, J, Inou, Jnou;
while( p <= u ){
I = Q[p].x;
J = Q[p].y;
for(k=1;k<=4;k++){
Inou = I + Dx[k];
Jnou = J + Dy[k];
w.x = Inou;
w.y = Jnou;
if( A[Inou][Jnou] == INF ){
A[Inou][Jnou] = A[I][J]+1;
Q[++u] = w;
}
}
p++;
}
}
int Parcurgere( int LIMITA ){
int k, I, J, Inou, Jnou;
memset(viz,0,sizeof(viz));
if( A[ST.x][ST.y] < LIMITA )
return 0;
p = 1; u = 1;
Q[1] = ST;
while( p <= u ){
I = Q[p].x;
J = Q[p].y;
for(k=1;k<=4;k++){
Inou = I + Dx[k];
Jnou = J + Dy[k];
w.x = Inou;
w.y = Jnou;
if( A[Inou][Jnou] != -1 && A[Inou][Jnou] >= LIMITA && viz[Inou][Jnou] == 0 ){
Q[++u] = w;
viz[Inou][Jnou] = 1;
if( Q[u].x == FN.x && Q[u].y == FN.y )
return 1;
}
}
p++;
}
return 0;
}
void CautareBinara(){
int p = 0, u = N+M-2, mij, sol = -1;
while( p <= u ){
mij = (p+u)/2;
if( Parcurgere(mij) == 1 ){
p = mij + 1;
sol = mij;
}
else
u = mij - 1;
}
fprintf(g,"%d",sol);
}
int main(){
Citire();
Preprocesare();
CautareBinara();
return 0;
}