#include <fstream>
#include<queue>
#include<cstring>
using namespace std;
ifstream fin("barbar.in");
ofstream fout("barbar.out");
int b[1005][1005],sol,R,C,i1,i2,j1,j2,maxx,i,j;
bool viz[1005][1005];
char ch;
struct camere
{
int l,c;
}poz,poz1;
queue<camere>q;
int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
bool verif(int x,int y)
{
if(x>=1&&x<=R&&y>=1&&y<=C)
return true;
return false;
}
int cautare(int x)
{
memset(viz,0,sizeof(viz));
if(b[i1][j1]<x)
return 0;
while(!q.empty())
q.pop();
viz[i1][j1]=1;
q.push({i1,j1});
while(!q.empty())
{
poz=q.front();
for(int nr=0;nr<4;nr++)
{
poz1.l=poz.l+dx[nr];
poz1.c=poz.c+dy[nr];
if(verif(poz1.l,poz1.c))
if(!viz[poz1.l][poz1.c] && b[poz1.l][poz1.c]>=x)
{
viz[poz1.l][poz1.c]=1;
if(poz1.l==i2 && poz1.c==j2)
return 1;
q.push(poz1);
}
}q.pop();
}
return 0;
}
int main()
{
fin>>R>>C;
for(i=1;i<=R;i++)
for(j=1;j<=C;j++)
{
fin>>ch;
if(ch=='*')
{
b[i][j]=-1;
}
else
if(ch=='I')
{
i1=i;
j1=j;
}
else
if(ch=='O')
{
i2=i;
j2=j;
}
else
if(ch=='D')
{
q.push({i,j});
b[i][j]=1;
}
}
while(!q.empty())
{
poz=q.front();
for(int nr=0;nr<4;nr++)
{
poz1.l=poz.l+dx[nr];
poz1.c=poz.c+dy[nr];
if(verif(poz1.l,poz1.c))
if(b[poz1.l][poz1.c]!=-1 && (b[poz1.l][poz1.c]==0||b[poz1.l][poz1.c]>b[poz.l][poz.c]+1))
{
b[poz1.l][poz1.c]=b[poz.l][poz.c]+1;
q.push(poz1);
}
} q.pop();
}
int st=1,dr=R,mijl;sol=-1;
while(st<=dr)
{
mijl=(st+dr)/2;
if(cautare(mijl))
{
sol=mijl-1;
st=mijl+1;
}
else
dr=mijl-1;
}
fout<<sol;
return 0;
}