#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream f("barbar.in");
ofstream g("barbar.out");
#define FREE 1002
#define WALL - 1
#define DRAGON 0
#define O 1003
#define I 1004
vector<int> DX,DY;
int M[1002][1002]={0};
int m,n;
int OX,OY,IX,IY;
void Read()
{
f>>m>>n;
char c;
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
f>>c;
switch(c)
{
case '.':M[i][j]=FREE; break;
case '*':M[i][j]=WALL; break;
case 'D':M[i][j]=DRAGON; DX.push_back(i); DY.push_back(j);
break;
case 'O':M[i][j]=O; OX=i,OY=j;
break;
case 'I':M[i][j]=I; IX=i,IY=j;
break;
}
}
}
}
int distmin=0;
void Check(int i,int x,int y,vector<int> &vX,vector<int> &vY)
{
if (M[DX[i]+x][DY[i]+y]==FREE)
vX.push_back(DX[i]+x), vY.push_back(DY[i]+y), M[DX[i]+x][DY[i]+y]=distmin;
}
void ExpandDragon()
{
distmin++;
vector<int> dX,dY;
int N=DX.size();
for(int i=0;i<N;i++)
{
Check(i,-1, 0,dX,dY);
Check(i, 1, 0,dX,dY);
Check(i, 0,-1,dX,dY);
Check(i, 0, 1,dX,dY);
}
DX=dX;
DY=dY;
}
vector<int> X(1,OX), Y(1,OY);
int D[1002][1002];
bool CheckS(int i,int x,int y,vector<int> &vX,vector<int> &vY)
{
int _i=X[i]+x, _j=Y[i]+y;
if (D[_i][_j]==FREE)
vX.push_back(_i), vY.push_back(_j), D[_i][_j]=1;
return (_i==IX && _j==IY);
}
bool Simulate()
{
X.clear(); X.push_back(OX);
Y.clear(); Y.push_back(OY);
bool result=0;
do
{
vector<int> sX(0,0),sY(0,0);
int N=X.size();
for(int i=0;i<N;i++)
{
result = CheckS(i,-1, 0,sX,sY) || CheckS(i, 1, 0,sX,sY) ||
CheckS(i, 0,-1,sX,sY) || CheckS(i, 0, 1,sX,sY) ;
}
/*for(int i=0;i<N;i++) cout<<X[i]<<" ";
cout<<endl;
for(int i=0;i<N;i++) cout<<Y[i]<<" ";
cout<<endl;
getchar();*/
X=sX, Y=sY;
} while(!result && X.size()!=0);
return result;
}
int main()
{
Read();
bool b=1;
while(b)
{
ExpandDragon();
copy(M,M+1002,D);
b=Simulate();
}
g<<distmin;
return 0;
}