#include<cstdio>
#include<cstring>
const int inf=0x7fffffff;
const int baza=10000;
int n,m,a[1001][1001],viz[1001][1001],l[1000001],st,dr,i,j,inc,fin,max;
char s[baza];
inline void go(int i,int j,int x)
{
if(i<1 || j<1 || i>n || j>m) return;
if(a[i][j]<=x+1) return;
a[i][j]=x+1;
l[++dr]=i*baza+j;
if(x+1>max) max=x+1;
}
inline void bf()
{
st=1;
while(st<=dr)
{
i=l[st]/baza;
j=l[st]%baza;
go(i-1,j,a[i][j]);
go(i+1,j,a[i][j]);
go(i,j+1,a[i][j]);
go(i,j-1,a[i][j]);
st++;
}
}
inline int go2(int i,int j,int k)
{
if(i<1 || j<1 || i>n || j>m) return 0;
if(a[i][j]<k) return 0;
if(viz[i][j]) return 0;
l[++dr]=i*baza+j;
viz[i][j]=1;
return l[dr]==fin;
}
inline int good(int k)
{
st=1;dr=1;
memset(viz,0,sizeof(viz));
l[st]=inc;
while(st<=dr)
{
i=l[st]/baza;
j=l[st]%baza;
if(go2(i-1,j,k)) return 1;
if(go2(i+1,j,k)) return 1;
if(go2(i,j-1,k)) return 1;
if(go2(i,j+1,k)) return 1;
st++;
}
return 0;
}
inline int seek(int s,int d)
{
if(d==0) return -1;
int m;
while(s<d)
{
m=(s+d+1)>>1;
if(good(m)) s=m;
else
d=m-1;
}
if(good(s))
return s;
return -1;
}
int main()
{
freopen("barbar.in","r",stdin);
freopen("barbar.out","w",stdout);
scanf("%d %d ",&n,&m);
for(i=1;i<=n;i++)
{
gets(s);
for(j=1;j<=m;j++)
switch(s[j-1])
{
case 'D':l[++dr]=i*baza+j;a[i][j]=0; break;
case 'I':inc=i*baza+j;a[i][j]=inf;break;
case 'O':fin=i*baza+j;a[i][j]=inf;break;
case '*':a[i][j]=-1;break;
case '.':a[i][j]=inf;break;
}
}
bf();
printf("%d\n",seek(1,a[inc/baza][inc%baza]));
fclose(stdout);
return 0;
}