#include<cstdio>
#include<cstring>
#include<algorithm>
#include<deque>
using namespace std;
const int nmax=1000;
int px[10],py[10];
char si[nmax+5][nmax+5];
int n,m,dist[nmax][nmax+5];
bool viz[nmax+5][nmax+5];
deque<pair<int,int> > dq;
bool bfs(pair<int,int> init,int d,pair<int,int> dest)
{
int i,x,y;
pair<int,int> tm;
dq.push_back(init);
viz[init.first][init.second]=1;
while(!dq.empty())
{
tm=dq.front();
dq.pop_front();
for(i=1;i<=4;i++)
{
x=tm.first+px[i];
y=tm.second+py[i];
if(viz[x][y]==0 && (si[x][y]=='.' || si[x][y]=='O' || si[x][y]=='D') && dist[x][y]>=d)
{
viz[x][y]=1;
dq.push_back(make_pair(x,y));
}
}
}
if(viz[dest.first][dest.second] && dist[init.first][init.second]>=d)
return 1;
else
return 0;
}
int main()
{
freopen("barbar.in","r",stdin);
freopen("barbar.out","w",stdout);
int x,y,i,j,d;
pair<int,int > tm,init,dest;
px[1]=1;px[2]=0;px[3]=-1;px[4]=0;
py[1]=0;py[2]=-1;py[3]=0;py[4]=1;
scanf("%d%d\n",&n,&m);
for(i=1;i<=n;i++)
gets(si[i]+1);
for(i=1;i<=n;i++)
dist[i][0]=dist[i][m+1]=-1;
for(i=1;i<=m;i++)
dist[0][i]=dist[n+1][i]=-1;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
if(si[i][j]=='D')
{
dist[i][j]=0;
dq.push_back(make_pair(i,j));
}
if(si[i][j]=='I')
{
init=make_pair(i,j);
}
if(si[i][j]=='*')
{
dist[i][j]=0;
}
if(si[i][j]=='O')
{
dest.first=i;
dest.second=j;
}
if(si[i][j]=='*')
{
dist[i][j]=-1;
}
}
while(!dq.empty())
{
tm=dq.front();
dq.pop_front();
d=max(dist[tm.first][tm.second],0);
for(i=1;i<=4;i++)
{
x=tm.first+px[i];
y=tm.second+py[i];
if(dist[x][y]==0 && (si[x][y]=='I' || si[x][y]=='.' || si[x][y]=='O'))
{
dist[x][y]=d+1;
dq.push_back(make_pair(x,y));
}
}
}
/*for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
printf("%d ",dist[i][j]);
}
printf("\n");
}*/
int st,dr,mi,la;
st=0;
dr=n*m;
la=-1;
while(st<=dr)
{
mi=(st+dr)/2;
if(bfs(init,mi,dest))
{
la=mi;
st=mi+1;
}
else
{
dr=mi-1;
}
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
viz[i][j]=0;
}
printf("%d\n",la);
return 0;
}