#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include <queue>
#include <tuple>
#include <cstring>
#define iv (i + di[d])
#define jv (j + dj[d])
using namespace std;
using PI = pair<int, int>;
using VI = vector<int>;
using VVI = vector<VI>;
ifstream fin("barbar.in");
ofstream fout("barbar.out");
const int INF = 0x3f3f3f3f, DIM = 1005,
di[] = {-1, 0, 1, 0},
dj[] = {0, 1, 0, -1};
int n, m;
int ip, jp, is, js;
VVI c, drg;
queue<PI> Q;
char a[DIM][DIM];
void GetData();
void LeeDragon(int i, int j, VVI& c);
void LeePaftenie(int i, int j, int ceil, VVI& c);
int CautareBinara();
bool Check(int i, int j);
bool Ok(int val);
void Debug(VVI c);
int main()
{
GetData();
fout << CautareBinara();
return 0;
}
int CautareBinara()
{
int st(1), dr(1e6), mij, rez(-1);
while (st <= dr)
{
mij = (st + dr) / 2;
//fout << mij << '\n';
if (Ok(mij))
{
rez = mij;
st = mij + 1;
}
else
dr = mij - 1;
}
return rez;
}
bool Ok(int val)
{
LeePaftenie(ip, jp, val, c);
if (c[is][js] != INF)
return true;
return false;
}
void LeeDragon(int i, int j, VVI& c)
{
c[i][j] = 1;
Q.emplace(i, j);
while (!Q.empty())
{
tie(i, j) = Q.front();
Q.pop();
for (int d = 0; d < 4; ++d)
if (Check(iv, jv) && c[iv][jv] > c[i][j] + 1)
{
c[iv][jv] = c[i][j] + 1;
Q.emplace(iv, jv);
}
}
}
void LeePaftenie(int i, int j, int ceil, VVI& c)
{
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
c[i][j] = INF;
c[i][j] = 1;
Q.emplace(i, j);
while (!Q.empty())
{
tie(i, j) = Q.front();
Q.pop();
for (int d = 0; d < 4; ++d)
if (Check(iv, jv) && drg[i][j] > ceil && c[iv][jv] > c[i][j] + 1)
{
c[iv][jv] = c[i][j] + 1;
Q.emplace(iv, jv);
}
}
}
bool Check(int i, int j)
{
if (i < 1 || i > n || j < 1 || j > m)
return false;
if (a[i][j] == '*')
return false;
return true;
}
void GetData()
{
fin >> n >> m;
c = VVI(n + 1, VI(m + 1, INF));
drg = VVI(n + 1, VI(m + 1, INF));
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
{
fin >> a[i][j];
if (a[i][j] == 'I')
ip = i, jp = j;
if (a[i][j] == 'O')
is = i, js = j;
}
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
if (a[i][j] == 'D')
LeeDragon(i, j, drg);
}
void Debug(VVI c)
{
for (int i = 1; i <= n; ++i, fout << '\n')
for (int j = 1; j <= m; ++j)
if (c[i][j] == INF)
fout << setw(3) << 0 << ' ';
else
fout << setw(3) << c[i][j] << ' ';
}