#include <cstdio>
#include <algorithm>
#include <queue>
#define x first
#define y second
#define MaxN 1001
using namespace std;
int R,C,StartX,StartY,EndX,EndY,MinDist[MaxN][MaxN],MaxRoad[MaxN][MaxN];
char Ch=' ',v[MaxN][MaxN];
bool used[MaxN][MaxN];
queue <pair<int,int>> Q;
int main()
{
freopen("barbar.in","r",stdin);
freopen("barbar.out","w",stdout);
scanf("%d%d",&R,&C);
while(Ch!='\n')
scanf("%c",&Ch);
for(int i=1;i<=R;i++)
{
for(int j=1;j<=C;j++)
{
scanf("%c",&v[i][j]);
if(v[i][j]=='I')
StartX=i,StartY=j;
if(v[i][j]=='O')
EndX=i,EndY=j;
if(v[i][j]=='D')
Q.push(make_pair(i,j)),used[i][j]=true,MinDist[i][j]=0;
}
if(i<R)
{
Ch=' ';
while(Ch!='\n')
scanf("%c",&Ch);
}
}
while(!Q.empty())
{
if(Q.front().x+1<=R&&!used[Q.front().x+1][Q.front().y]&&v[Q.front().x+1][Q.front().y]!='*')
Q.push(make_pair(Q.front().x+1,Q.front().y)),MinDist[Q.front().x+1][Q.front().y]=1+MinDist[Q.front().x][Q.front().y],used[Q.front().x+1][Q.front().y]=true;
if(Q.front().x-1>0&&!used[Q.front().x-1][Q.front().y]&&v[Q.front().x-1][Q.front().y]!='*')
Q.push(make_pair(Q.front().x-1,Q.front().y)),MinDist[Q.front().x-1][Q.front().y]=1+MinDist[Q.front().x][Q.front().y],used[Q.front().x-1][Q.front().y]=true;
if(Q.front().y+1<=C&&!used[Q.front().x][Q.front().y+1]&&v[Q.front().x][Q.front().y+1]!='*')
Q.push(make_pair(Q.front().x,Q.front().y+1)),MinDist[Q.front().x][Q.front().y+1]=1+MinDist[Q.front().x][Q.front().y],used[Q.front().x][Q.front().y+1]=true;
if(Q.front().y-1>0&&!used[Q.front().x][Q.front().y-1]&&v[Q.front().x][Q.front().y-1]!='*')
Q.push(make_pair(Q.front().x,Q.front().y-1)),MinDist[Q.front().x][Q.front().y-1]=1+MinDist[Q.front().x][Q.front().y],used[Q.front().x][Q.front().y-1]=true;
Q.pop();
}
for(int i=1;i<+R;i++)
for(int j=1;j<=R;j++)
MaxRoad[i][j]=-1;
Q.push(make_pair(StartX,StartY)),MaxRoad[StartX][StartY]=MinDist[StartX][StartY];
while(!Q.empty())
{
if(Q.front().x+1<=R&&v[Q.front().x+1][Q.front().y]!='*'&&MaxRoad[Q.front().x+1][Q.front().y]<min(MinDist[Q.front().x+1][Q.front().y],MaxRoad[Q.front().x][Q.front().y]))
Q.push(make_pair(Q.front().x+1,Q.front().y)),MaxRoad[Q.front().x+1][Q.front().y]=min(MinDist[Q.front().x+1][Q.front().y],MaxRoad[Q.front().x][Q.front().y]);
if(Q.front().x-1>0&&v[Q.front().x-1][Q.front().y]!='*'&&MaxRoad[Q.front().x-1][Q.front().y]<min(MinDist[Q.front().x-1][Q.front().y],MaxRoad[Q.front().x][Q.front().y]))
Q.push(make_pair(Q.front().x-1,Q.front().y)),MaxRoad[Q.front().x-1][Q.front().y]=min(MinDist[Q.front().x-1][Q.front().y],MaxRoad[Q.front().x][Q.front().y]);
if(Q.front().y+1<=C&&v[Q.front().x][Q.front().y+1]!='*'&&MaxRoad[Q.front().x][Q.front().y+1]<min(MinDist[Q.front().x][Q.front().y+1],MaxRoad[Q.front().x][Q.front().y]))
Q.push(make_pair(Q.front().x,Q.front().y+1)),MaxRoad[Q.front().x][Q.front().y+1]=min(MinDist[Q.front().x][Q.front().y+1],MaxRoad[Q.front().x][Q.front().y]);
if(Q.front().y-1>0&&v[Q.front().x][Q.front().y-1]!='*'&&MaxRoad[Q.front().x][Q.front().y-1]<min(MinDist[Q.front().x][Q.front().y-1],MaxRoad[Q.front().x][Q.front().y]))
Q.push(make_pair(Q.front().x,Q.front().y-1)),MaxRoad[Q.front().x][Q.front().y-1]=min(MinDist[Q.front().x][Q.front().y-1],MaxRoad[Q.front().x][Q.front().y]);
Q.pop();
}
printf("%d",MaxRoad[EndX][EndY]);
return 0;
}