///lee din dragoni,apoi caut binar distanta minima maxima si verific cu lee
///O(n*m*log(n*m))
#include <bits/stdc++.h>
using namespace std;
ifstream fin("barbar.in");
ofstream fout("barbar.out");
const int NMAX = 1e3+3;
int mat[NMAX][NMAX], aux[NMAX][NMAX];
bool viz[NMAX][NMAX];
///N E S V
int dirx[] = {-1, 0, 1, 0},
diry[] = {0, 1, 0, -1};
int n, m, starti, startj;
queue <pair <int, int> >coada;
bool exist(int lin, int col)
{
if(lin < 1 || lin > n)
return false;
if(col < 1 || col > m)
return false;
if(viz[lin][col])
return false;
if(aux[lin][col] == -1)
return false;
return true;
}
void lee()
{
int lin, col, i;
while(!coada.empty())
{
lin = coada.front().first;
col = coada.front().second;
coada.pop();
for(i = 0; i < 4; ++i)
if(exist(lin+dirx[i], col+diry[i]))
{
viz[lin+dirx[i]][col+diry[i]] = true;
mat[lin+dirx[i]][col+diry[i]] = mat[lin][col] + 1;
coada.push({lin+dirx[i], col+diry[i]});
}
}
}
void init()
{
int i, j;
for(i = 1; i <= n; ++i)
for(j = 1; j <= m; ++j)
{
viz[i][j] = true;
if(aux[i][j] != -1) aux[i][j] = 0; viz[i][j] = false;
}
}
void lee_barbar(int &startlin, int &startcol, int lim)
{
init();
coada.push({startlin, startcol});
aux[startlin][startcol] = 1;
viz[startlin][startcol] = true;
int lin, col, i;
while(!coada.empty())
{
lin = coada.front().first;
col = coada.front().second;
coada.pop();
for(i = 0; i < 4; ++i)
if(exist(lin+dirx[i], col+diry[i]) && mat[lin+dirx[i]][col+diry[i]] >= lim)
{
viz[lin+dirx[i]][col+diry[i]] = true;
aux[lin+dirx[i]][col+diry[i]] = aux[lin][col] + 1;
coada.push({lin+dirx[i], col+diry[i]});
}
}
}
int ajuns(int &startlin, int &startcol, int &stoplin, int &stopcol, int mij)
{
lee_barbar(startlin, startcol, mij);
return aux[stoplin][stopcol];
}
void bs(int &startlin, int &startcol, int &stoplin, int &stopcol)
{
int st, dr, mij, sol=0;
st = 0, dr = 1000*1000;
while(st <= dr)
{
mij = (st+dr) / 2;
///daca am solutie caut in dreapta
if(ajuns(startlin, startcol, stoplin, stopcol, mij) > 0)
sol = mij, st = mij + 1;
else dr = mij - 1;
}
fout << sol;
}
int main()
{
char ch;
int i, j, startlin, startcol, stoplin, stopcol;
fin >> n >> m;
for(i = 1; i <= n; ++i)
for(j = 1; j <= m; ++j)
{
fin >> ch, aux[i][j] = mat[i][j] = (ch=='*') ? -1 : 0;
if(ch == 'D')
coada.push({i, j}), viz[i][j] = true;
else if(ch == 'I')
startlin = i, startcol = j;
else if(ch == 'O')
stoplin = i, stopcol = j;
}
lee();
bs(startlin, startcol, stoplin, stopcol);
return 0;
}