#include <stdio.h>
#include <string.h>
#define maxr 1005
#define inf 1<<30
struct queue
{
int l, c;
};
int r, c, st, dr, max, m [maxr] [maxr];
char w [maxr] [maxr];
queue I, O, q [5*maxr*maxr];
void init ()
{
int i, j, cr=r+1, cc=c+1;
for (i=0; i<=cr; ++i)
for (j=0; j<=cc; ++j)
m [i] [j]=inf;
memset (w, '*', sizeof (w));
}
void scan ()
{
int i, j;
scanf ("%d%d\n", &r, &c);
init ();
for (i=1; i<=r; ++i)
for (j=1; j<=c; ++j)
{
scanf ("%c\n", &w [i] [j]);
if (w [i] [j] != '.')
{
if (w [i] [j] == 'D')
{
q [++dr].l=i;
q [dr].c=j;
m [i] [j]=0;
}
else
if (w [i] [j] == 'I')
{
I.l=i;
I.c=j;
}
else
if (w [i] [j] == 'O')
{
O.l=i;
O.c=j;
}
}
}
}
void bfs_1 ()
{
int i, x, y, dl []={0, 0, 0, 1, -1}, dc []={0, 1, -1, 0, 0};
while (st < dr)
{
++st;
for (i=1; i<=4; ++i)
{
x=q [st].l+dl [i];
y=q [st].c+dc [i];
if ((w [x] [y] != '*') && (m [x] [y] > m [q [st].l] [q [st].c]+1))
{
m [x] [y]=m [q [st].l] [q [st].c]+1;
if (m [x] [y] > max)
max=m [x] [y];
q [++dr].l=x;
q [dr].c=y;
}
}
}
}
int bfs_2 (int k)
{
int st, dr, x, y, i, dl []={0, 0, 0, 1, -1}, dc []={0, 1, -1, 0, 0};
char viz [maxr] [maxr];
if (m [I.l] [I.c] < k)
return 0;
memset (viz, 0, sizeof (viz));
st=0;
dr=1;
q [dr]=I;
viz [I.l] [I.c]=1;
while (st < dr)
{
++st;
for (i=1; i<=4; ++i)
{
x=q [st].l+dl [i];
y=q [st].c+dc [i];
if ((m [x] [y] >= k) && (m [x] [y] < inf) && (!viz [x] [y]))
{
q [++dr].l=x;
q [dr].c=y;
viz [x] [y]=1;
if ((q [dr].l == O.l) && (q [dr].c == O.c))
return 1;
}
}
}
return 0;
}
int bs ()
{
int s, i;
for (s=1; s<=max; s<<=1);
for (i=0; s>0; s>>=1)
if ((i+s<=max) && (bfs_2 (i+s)))
i+=s;
if ((i == 0) && (!bfs_2 (0)))
return -1;
return i;
}
int main ()
{
freopen ("barbar.in", "r", stdin);
freopen ("barbar.out", "w", stdout);
scan ();
bfs_1 ();
printf ("%d\n", bs ());
return 0;
}