#include<iostream>
#include<fstream>
#include<queue>
#include<iomanip>
#define MAX 1010 //limite
using namespace std;
fstream fin("barbar.in",ios::in),fout("barbar.out",ios::out);
int di[]={-1,0,1,0},dj[]={0,1,0,-1},x[MAX][MAX],ap[MAX][MAX];//vectori de directii,matricea de distante,matrice pt bifat dfs
int si,sj,fi,fj,r,c,ok,mij; //start,final,limite
queue <pair<int,pair<int,int>> > q;
bool into(int i,int j)
{
return (0<i && 0<j && i<=r && j<=c);
}
void bfs()
{
int i,j,k,cost,a,b;
while(!q.empty())
{
i=q.front().first;
j=q.front().second.first;
cost=q.front().second.second;
for(k=0;k<4;k++)
{
a=i+di[k]; b=j+dj[k];
if(x[a][b]==0 || x[a][b]>cost+1)
{
if(into(a,b)==1)
{
x[a][b]=cost+1;
q.push(make_pair(a,make_pair(b,cost+1)));
}
}
}
q.pop();
}
}
void dfs(int i,int j,int minim)
{
if(ok==1) return;
if(i==fi && j==fj && minim>=mij) ok=1;
int a,b,k;
ap[i][j]=1;
for(k=0;k<4;k++)
{
a=i+di[k];b=j+dj[k];
if(ap[a][b]==0 && into(a,b)==1)
{
if(mij<=x[a][b]) dfs(a,b,min(minim,x[a][b]));
}
}
ap[i][j]=0;
}
int main()
{
int i,j,k,a,b,pre,act,start,stop;
char w;
fin>>r>>c;
for(i=1;i<=r;i++)
{
for(j=1;j<=c;j++)
{
fin>>w;
if(w=='D')
{
x[i][j]=-1;
q.push(make_pair(i,make_pair(j,0)));
}
if(w=='*') x[i][j]=-2;
if(w=='I') si=i,sj=j;
if(w=='O') fi=i,fj=j;
}
}
bfs();
start=1;
stop=min(x[si][sj],x[fi][fj]);
while(start<stop)
{
mij=(start+stop+1)/2;
ok=0;
dfs(si,sj,x[si][sj]);
if(ok==0)
stop=mij-1;
else
start=mij;
}
fout<<start;
return 0;
}