#include <iostream>
#include <vector>
#include <queue>
#include <fstream>
using namespace std;
ifstream in ("barbar.in");
ofstream out ("barbar.out");
bool drum(int n, int R, int C, pair<int, int> paftenie, pair<int, int> Final, vector< vector<int> > dragon)
{
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
vector< vector<int> > Hero(R, vector<int> (C, R * C + 2));
Hero[paftenie.first][paftenie.second] = 0;
queue< pair<int, int> > Q;
Q.push(paftenie);
if (dragon[paftenie.first][paftenie.second] >= n)
while (not Q.empty())
{
pair<int, int> node = Q.front();
Q.pop();
for (int i = 0; i < 4; i++)
{
pair<int, int> vecin = make_pair(node.first + dx[i], node.second + dy[i]);
if (vecin.first < 0 || vecin.second < 0 || vecin.first >= R || vecin.second >= C)
continue;
if (dragon[vecin.first][vecin.second] < n || dragon[vecin.first][vecin.second] == R * C + 2)
continue;
if (Hero[vecin.first][vecin.second] > Hero[node.first][node.second] + 1)
{
Hero[vecin.first][vecin.second] = Hero[node.first][node.second] + 1;
Q.push(vecin);
}
}
}
if (Hero[Final.first][Final.second] != R * C + 2)
return true;
else
return false;
}
int main()
{
int R, C, nr = 0, Max = 0;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
in>> R >> C;
vector<string> traseu(R);
pair<int, int> paftenie, Final;
vector< pair<int, int> > D;
for (int i = 0; i < R; i++)
{
in>> traseu[i];
for (int j = 0; j < C; j++)
{
if (traseu[i][j] == 'I')
paftenie = make_pair(i, j);
if (traseu[i][j] == 'D')
{
D.push_back(make_pair(i, j));
nr++;
}
if (traseu[i][j] == 'O')
Final = make_pair(i, j);
}
}
vector< vector<int> > dragon(R, vector<int> (C, R * C + 2));
queue< pair<int, int> > Q;
for (int i = 0; i < nr; i++)
{
dragon[D[i].first][D[i].second] = 0;
Q.push(D[i]);
}
while (not Q.empty())
{
pair<int, int> node = Q.front();
Q.pop();
for (int i = 0; i < 4; i++)
{
pair<int, int> vecin = make_pair(node.first + dx[i], node.second + dy[i]);
if (vecin.first < 0 || vecin.second < 0 || vecin.first >= R || vecin.second >= C)
continue;
if (traseu[vecin.first][vecin.second] == '*')
continue;
if (dragon[vecin.first][vecin.second] > dragon[node.first][node.second] + 1)
{
dragon[vecin.first][vecin.second] = dragon[node.first][node.second] + 1;
Q.push(vecin);
if (dragon[vecin.first][vecin.second] > Max)
Max = dragon[vecin.first][vecin.second];
}
}
}
int c1 = 1, c2 = Max;
if (nr == 0)
out<< 0;
else
if (not drum(0, R, C, paftenie, Final, dragon))
out<< -1;
else
{
while (c2 - c1 > 1)
{
int m = (c1 + c2) / 2;
if (drum(m, R, C, paftenie, Final, dragon))
c1 = m;
else
c2 = m;
}
if (drum(c2, R, C, paftenie, Final, dragon))
out<< c2;
else
out<< c1;
}
in.close();
out.close();
return 0;
}