#define DM 1001
#include <cstring>
#include <fstream>
#include <queue>
#include <vector>
using namespace std;
ifstream fi ("barbar.in");
ofstream fo ("barbar.out");
char c[DM][DM];
int n, m, dist[DM][DM], a, b, di[4] = {-1, 0, 1, 0}, dj[4] = {0, 1, 0, -1}, viz[DM][DM], endi, endj;
queue <pair <int, int> > q;
vector <pair <int, int> > v;
int ok(int x, int y){
return(x > 0 && y > 0 && x <= n && y <= m);
}
int bfs(int x)
{
for (int i = 1; i <= n; ++i)
memset(viz[i], 0, m);
for (int i = 0; i < v.size(); ++i)
{
q.push(v[i]);
viz[v[i].first][v[i].second] = dist[v[i].first][v[i].second];
}
while (!q.empty())
{
a = q.front().first, b = q.front().second;
q.pop();
for (int i = 0; i < 4; ++i)
if (ok(a + di[i], b + dj[i]) && dist[a+di[i]][b+dj[i]] >= x && !viz[a+di[i]][b+dj[i]] && c[a+di[i]][b+dj[i]] == '.')
{
viz[a+di[i]][b+dj[i]] = min(dist[a+di[i]][b+dj[i]], viz[a][b]);
q.push({a + di[i], b + dj[i]});
}
}
if (viz[endi][endj])
return 1;
return 0;
}
int binar()
{
int hi = n + m, lo = 1, mid;
while (hi > lo)
{
mid = (lo + hi + 1)/2;
if (bfs(mid))
lo = mid;
else
hi = mid - 1;
}
return mid;
}
int main()
{
fi >> n >> m;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
{
dist[i][j] = (1<<30);
fi >> c[i][j];
if (c[i][j] == 'D')
{
dist[i][j] = 0;
q.push({i, j});
}
else if (c[i][j] == 'I')
v.push_back({i, j});
else if (c[i][j] == 'O')
endi = i, endj = j;
}
while (!q.empty())
{
a = q.front().first, b = q.front().second;
q.pop();
for (int i = 0; i < 4; ++i)
if (ok(a + di[i], b + dj[i]) && dist[a+di[i]][b+dj[i]] > dist[a][b] + 1)
{
dist[a+di[i]][b+dj[i]] = dist[a][b] + 1;
q.push({a + di[i], b + dj[i]});
}
}
fo << binar();
return 0;
}