#include <fstream>
using namespace std;
ifstream in("barbar.in");
ofstream out("barbar.out");
const int MAXN = 1005;
inline int abs(int x)
{
return (x < 0)?-x:x;
}
struct coordonata
{
int x,y;
coordonata operator + (coordonata &c)
{
coordonata rasp;
rasp.x = this -> x + c.x;
rasp.y = this -> y + c.y;
return rasp;
}
bool operator == (coordonata &c)
{
return this -> x == c.x && this -> y == c.y;
}
};
bool zid[MAXN][MAXN];
int dist[MAXN][MAXN];
int n,m;
coordonata start,finish;
coordonata dragon[MAXN * MAXN];
int nrdragoni = 0;
int vizitat[MAXN][MAXN];//retine momentul de timp cand a fost vizitat
int timp = 1;
void citire()
{
char sir[MAXN];
in >> n >> m;
for (int i = 1;i <= n;++i)
{
zid[i][0] = true;
zid[i][m + 1] = true;
vizitat[i][0] = true;
vizitat[i][m + 1] = true;
in >> (sir + 1);
for (int j = 1;j <= m;++j)
{
zid[0][j] = true;
zid[n + 1][j] = true;
vizitat[0][j] = true;
vizitat[n + 1][j] = true;
if (sir[j] == 'I')
{
start.x = i;
start.y = j;
}
if (sir[j] == 'O')
{
finish.x = i;
finish.y = j;
}
if (sir[j] == 'D')
{
++nrdragoni;
dragon[nrdragoni].x = i;
dragon[nrdragoni].y = j;
}
if (sir[j] == '*')
zid[i][j] = true;
}
}
}
coordonata coada[MAXN * MAXN];
int p,q;
coordonata off[4] = { (coordonata){-1,0} , (coordonata){1,0} , (coordonata){0,1} , (coordonata){0,-1} };
bool dfs(int r)
{
if (dist[start.x][start.y] < r)
return false;
p = 1, q = 1;
coada[1] = start;
++timp;
vizitat[start.x][start.y] = timp;
while (p <= q)
{
coordonata c = coada[p];
++p;
for (int dir = 0; dir < 4;++dir)
{
coordonata vecin = c + off[dir];
if (zid[vecin.x][vecin.y] || vizitat[vecin.x][vecin.y] == timp || dist[vecin.x][vecin.y] < r)
continue;
coada[++q] = vecin;
vizitat[vecin.x][vecin.y] = timp;
if (vecin == finish)
return true;
}
}
return false;
}
int cautare_binara()
{
int poz = 0;
for (int pas = 1 << 11;pas >= 1;pas >>= 1)
{
int r = poz + pas;
if (r <= n && r <= m && dfs(r))
poz += pas;
}
return poz;
}
void calculare_dragoni()
{
p = 1,q = 0;
for (int i = 1;i <= nrdragoni;++i)
{
coada[++q] = dragon[i];
vizitat[dragon[i].x][dragon[i].y] = true;
}
while (p <= q)
{
coordonata c = coada[p];
++p;
for (int dir = 0; dir < 4;++dir)
{
coordonata vecin = c + off[dir];
if (vizitat[vecin.x][vecin.y] || zid[vecin.x][vecin.y])
continue;
coada[++q] = vecin;
vizitat[vecin.x][vecin.y] = true;
dist[vecin.x][vecin.y] = dist[c.x][c.y] + 1;
}
}
}
int main()
{
citire();
calculare_dragoni();
int raspuns = cautare_binara();
if (raspuns == 0)
out << -1 << '\n';
else out << raspuns << '\n';
return 0;
}