#include <iostream>
#include <fstream>
using namespace std;
ifstream in("barbar.in");
ofstream out("barbar.out");
short int dl[] = {-1,0,1,0};
short int dc[] = {0,1,0,-1};
struct element
{
int l;
int c;
};
int n,m;
char a[1002][1002];
int b[1002][1002];
int c[1002][1002];
element q[1002*1002];
int st = 0,dr = -1,xs,ys,xf,yf;
void Golire()
{
for (int i=1; i<= n; i++)
{
for (int j=1; j<=m; j++)
{
c[i][j] = 0;
}
}
}
void Bordare()
{
int i,j;
for (i=0; i<=n+1; i++)
{
a[i][0] = a[i][m+1] = -2;
}
for (j=0; j<=m+1; j++)
{
a[0][j] = a[n+1][j] = -2;
}
}
bool exista_drum(int val)
{
element x,y;
st = 0;
dr = -1;
Golire();
c[xs][ys] = 1;
q[++dr] = (element){xs,ys};
while (st <= dr)
{
x = q[st++];
for (int k=0; k<4; k++)
{
y.l = x.l + dl[k];
y.c = x.c + dc[k];
if ((b[y.l][y.c] >= val || b[y.l][y.c] == -1) && c[y.l][y.c] == 0)
{
c[y.l][y.c] = 1 + c[x.l][x.c];
q[++dr] = y;
}
}
}
return (c[xf][yf] != 0);
}
int Cautare()
{
int st = 0,dr = 2000,mij,val = -1;
while (st < dr)
{
mij = (st+dr)/2;
if (exista_drum(mij))
{
st = mij+1;
val = mij;
}
else
{
dr = mij;
}
}
return val;
}
void Lee()
{
element x,y;
b[xs][ys] = 1;
while (st <= dr)
{
x = q[st++];
for (int k=0; k<4; k++)
{
y.l = x.l + dl[k];
y.c = x.c + dc[k];
if (b[y.l][y.c] == 0 && a[y.l][y.c] == '.')
{
b[y.l][y.c] = b[x.l][x.c] + 1;
q[++dr] = y;
}
}
}
}
int main()
{
int i,j;
in >> n >> m;
Bordare();
for (i=1; i<=n; i++)
{
in >> (1+a[i]);
for (j=1; j<=m; j++)
{
if (a[i][j] == 'I')
{
xs = i;
ys = j;
}
if (a[i][j] == 'O')
{
xf = i;
yf = j;
}
if (a[i][j] == 'D')
{
q[++dr] = (element){i,j};
}
if (a[i][j] == '*')
{
b[i][j] = -2;
}
}
}
Lee();
b[xs][ys] = -1;
b[xf][yf] = -1;
/*for (i=1; i<=n; i++)
{
for (j=1; j<=m; j++)
{
cout << b[i][j] << " ";
}
cout << endl;
}*/
out << Cautare();
return 0;
}