#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];
bool zidpred[MAXN][MAXN];
int n,m;
coordonata start,finish;
coordonata dragon[MAXN * MAXN];
int nrdragoni = 0;
void citire()
{
char sir[MAXN];
in >> n >> m;
for (int i = 1;i <= n;++i)
{
zid[i][0] = true;
zid[i][m + 1] = true;
in >> (sir + 1);
for (int j = 1;j <= m;++j)
{
zid[0][j] = true;
zid[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;
}
}
for (int i = 1;i <= n;++i)
for (int j = 1;j <= m;++j)
zidpred[i][j] = zid[i][j];
}
coordonata coada[MAXN * MAXN];
int p,q;
coordonata off[4] = { (coordonata){-1,0} , (coordonata){1,0} , (coordonata){0,1} , (coordonata){0,-1} };
void peretare(int r)
{
for (int d = 1;d <= nrdragoni;++d)
{
int x = dragon[d].x;
int y = dragon[d].y;
for (int i = max(1, x - r);i <= min (n, x + r);++i)
for (int j = max(1, y - r);j <= min(m, y + r);++j)
if (abs(x - i) + abs(y - j) <= r)
zid[i][j] = true;
}
/*for (int i = 1;i <= n;++i)
{
for (int j = 1;j <= m;++j)
printf("%c", (zid[i][j])?'*':'.');
printf("\n");
}
printf("\n");*/
}
void deperetare()
{
for (int i = 1;i <= n;++i)
for (int j = 1;j <= m;++j)
zid[i][j] = zidpred[i][j];
}
int vizitat[MAXN][MAXN];//retine momentul de timp cand a fost vizitat
int timp = 0;
bool dfs(int r)
{
peretare(r - 1);
if (zid[start.x][start.y])
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)
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;
deperetare();
}
return poz;
}
int main()
{
citire();
int raspuns = cautare_binara();
if (raspuns == 0)
out << -1 << '\n';
else out << raspuns << '\n';
return 0;
}