#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
#define MAXN 1005
#define INF 999999999
int N, M, i, j, X1, Y1, X2, Y2, x, y, xn, yn, st, mid, end, res;
int A[ MAXN ][ MAXN ], B[ MAXN ][ MAXN ], D[ MAXN ][ MAXN ], d[4][2];
char S[ MAXN ];
queue < pair < int, int > > Q;
int main()
{
FILE *f, *g;
f = fopen("barbar.in", "r");
g = fopen("barbar.out", "w");
fscanf(f, "%d %d", &N, &M);
fgets(S, 3, f);
for(i = 0; i <= N + 1; ++i)
for(j = 0; j <= M + 1; ++j)
D[i][j] = INF;
for(i = 0; i <= N+1; ++i)
A[i][0] = A[i][M+1] = 1;
for(j = 0; j <= M+1; ++j)
A[0][j] = A[N+1][j] = 1;
for(i = 1; i <= N; ++i)
{
fgets(S, 1003, f);
for(j = 0; j < M; ++j)
if(S[j] == '*')
A[i][j+1] = 1;
else if(S[j] == 'D')
Q.push(make_pair(i, j+1)), D[i][j+1] = 0, A[i][j+1] = 2;
else if(S[j] == 'I')
X1 = i, Y1 = j+1;
else if(S[j] == 'O')
X2 = i, Y2 = j + 1;
}
d[0][0] = 1;
d[1][0] = -1;
d[2][1] = 1;
d[3][1] = -1;
while(!Q.empty())
{
x = Q.front().first;
y = Q.front().second;
Q.pop();
for(i = 0; i < 4; ++i)
{
xn = x + d[i][0], yn = y + d[i][1];
if(D[x][y] + 1 < D[xn][yn] && A[xn][yn] != 1)
D[xn][yn] = D[x][y] + 1, Q.push(make_pair(xn, yn));
}
}
end = N + M;
while(st <= end)
{
mid = (st + end) / 2;
memset(B, 0, sizeof(B));
if(D[X1][Y1] >= mid)
Q.push(make_pair(X1, Y1)), B[X1][Y1] = 1;
while(!Q.empty())
{
x = Q.front().first;
y = Q.front().second;
Q.pop();
for(i = 0; i < 4; ++i)
{
xn = x + d[i][0], yn = y + d[i][1];
if(!B[xn][yn] && !A[xn][yn] && D[xn][yn] >= mid)
B[xn][yn] = 1, Q.push(make_pair(xn, yn));
}
}
if(B[X2][Y2])
st = mid + 1, res = mid;
else end = mid - 1;
}
fprintf(g, "%d\n", res);
fclose(f);
fclose(g);
return 0;
}