#include <fstream>
#include <queue>
using namespace std;
ifstream fin("barbar.in");
ofstream fout("barbar.out");
int mat[1005][1005],lee[1005][1005],rez[1005][1005];
int r,c,nrDrag,poz;
int dx[4]={0,0,1,-1},dy[4]={-1,1,0,0};
pair <int,int> drag[1000005],start,final;
queue <pair<int,int>> q;
void bordare(int a[][1005])
{
for (int i=0;i<=r+1;i++)
{
a[i][0]=a[i][c+1]=-1;
}
for (int j=0;j<=c+1;j++)
{
a[0][j]=a[r+1][j]=-1;
}
}
void algLee()
{
while (!q.empty())
{
int okx=q.front().first;
int oky=q.front().second;
q.pop();
for (int i=0;i<4;i++)
{
int x2=okx+dx[i];
int y2=oky+dy[i];
if ((lee[x2][y2]>lee[okx][oky]+1 || lee[x2][y2]==0) && mat[x2][y2]!=-1)
{
lee[x2][y2]=lee[okx][oky]+1;
q.push(make_pair(x2,y2));
}
}
}
}
int drum(int mij)
{
for (int i=1;i<=r;i++)
{
for (int j=1;j<=c;j++)
{
rez[i][j] = 0;
}
}
while (!q.empty())
{
q.pop();
}
rez[start.first][start.second]=1;
if (lee[start.first][start.second]>=mij) q.push(start);
while (!q.empty())
{
int okx=q.front().first;
int oky=q.front().second;
q.pop();
if (okx==final.first && oky==final.second) return 1;
for (int i=0;i<4;i++)
{
int x2=okx+dx[i];
int y2=oky+dy[i];
if ((lee[x2][y2]>=mij) && (rez[x2][y2]>rez[okx][oky]+1 || rez[x2][y2]==0))
{
rez[x2][y2]=rez[okx][oky]+1;
q.push(make_pair(x2,y2));
}
}
}
return 0;
}
void cautBin(int st, int dr)
{
while (st <= dr)
{
int mij=(st + dr)/2;
if (drum(mij)==1)
{
poz=mij;
st=mij+1;
}
else dr=mij-1;
}
}
int main()
{
fin >> r >> c;
bordare(lee);
bordare(rez);
for (int i = 1; i <= r; i++)
for (int j = 1; j <= c; j++)
{
char x;
fin >> x;
if (x=='.') mat[i][j]=0;
else if (x=='*') mat[i][j]=-1;
else if (x=='D')
{
mat[i][j]=-1;
drag[++nrDrag]=make_pair(i,j);
}
else if (x=='I')
{
mat[i][j]=0;
start=make_pair(i,j);
}
else if (x=='O')
{
mat[i][j]=0;
final=make_pair(i, j);
}
}
for (int i=1;i<=nrDrag;i++)
{
q.push(make_pair(drag[i].first,drag[i].second));
}
algLee();
cautBin(0,r*c);
if (poz == 0) poz = -1;
fout << poz << "\n";
}