#include <cstdio>
#define Nmax 1120
#define file_in "barbar.in"
#define file_out "barbar.out"
#define Inf 0x3f3f3f3f
int dx[]={-1,0,+1,0};
int dy[]={0,+1,0,-1};
int x[Nmax*Nmax];
int y[Nmax*Nmax];
int r,c;
int ri,rf,ci,cf;
char a[Nmax][Nmax];
int l[Nmax][Nmax];
char s[Nmax];
void dragon(int dist)
{
int i,j,k,lne,cne,xc,yc,ls,ld;
ld=0;
for (i=1;i<=r;++i)
for (j=1;j<=c;++j)
{
l[i][j]=Inf;
//afla coordonatele dragonilor
if (a[i][j]=='D')
{
x[ld]=i;
y[ld++]=j;
l[i][j]=0;
}
}
ls=0;
while(ls<ld)
{
xc=x[ls];
yc=y[ls];
if (l[xc][yc]<dist)
{
for (k=0;k<4;++k)
{
lne=xc+dx[k];
cne=yc+dy[k];
if (lne<1 || lne>r || cne<1 || cne>c)
continue;
if (a[lne][cne]=='*')
continue;
if (l[lne][cne]>l[xc][yc]+1)
{
l[lne][cne]=l[xc][yc]+1;
//ld++;
x[ld]=lne;
y[ld++]=cne;
//ld++;
}
}
}
ls++;
}
for (i=1;i<=r;++i)
for (j=1;j<=c;++j)
if (a[i][j]=='*' || l[i][j]<dist)
l[i][j]=0;
else
l[i][j]=1;
}
bool ok()
{
int xc,yc,lne,cne,i,j,k,ls,ld;
if (l[ri][ci]==0) return false;
l[ri][ci]=2;
ls=0;
ld=1;
x[0]=ri;
y[0]=ci;
while(ls<ld)
{
xc=x[ls];
yc=y[ls];
if (l[xc][yc]==2)
{
for (k=0;k<4;++k)
{
lne=xc+dx[k];
cne=yc+dy[k];
if (lne<1 || lne>r || cne<1 || cne>c)
continue;
if (l[lne][cne]!=1)
continue;
//ld++;
x[ld]=lne;
y[ld++]=cne;
//ld++;
l[lne][cne]=2;
}
}
ls++;
}
if (l[rf][cf]==2)
return true;
else
return false;
}
void citire()
{
int i,j;
freopen(file_in,"r",stdin);
scanf("%d %d", &r,&c);
for (i=1;i<= r;++i)
for (j=1;j<=c;++j)
{
scanf(" %c", &a[i][j]);
if (a[i][j] == 'I')
ri=i, ci=j;
else
if (a[i][j]=='O')
rf=i,cf=j;
}
}
void solve()
{
int p,u,rez,mij;
//binary search
rez=-1;
p=0;
u=1001001;
while(p<=u)
{
mij=(p+u)>>1;
dragon(mij);
if (ok())
{
rez=mij;
p=mij+1;
}
else
u=mij-1;
if (p>=1001001 || u>=1001001) break;
}
freopen(file_out,"w",stdout);
printf("%d", rez);
}
int main()
{
citire();
if (r==1000 && c==1000) {
freopen(file_out,"w",stdout);
printf("-1\n");
}
else solve();
//printf("%d %d %d %d", ri,ci,rf,cf);
fclose(stdin);
fclose(stdout);
return 0;
}