#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define FIN "barbar.in"
#define FOUT "barbar.out"
#define MAXN 1000
#define INF 0x3f3f3f3f
struct punct { int x, y; };
int n, m, q=0, q0, cc;
punct C[2][4*MAXN*MAXN], st, fin;
char A[MAXN+2][MAXN+2];
int D[MAXN+2][MAXN+2], M[MAXN+2][MAXN+2];
int dx[] = {1, 0, 0,-1},
dy[] = {0,-1, 1, 0};
template <typename fn>
void lee(fn _comp) {
int x, y;
while (q) {
for (int p=0; p<q; ++p) {
for (int i=0; i<4; ++i) {
x=C[cc][p].x + dx[i], y = C[cc][p].y + dy[i];
if (A[x][y] && A[x][y] != '*' &&
_comp(D [C[cc][p].x][C[cc][p].y]+1, D[x][y])) {
// e mai avantajos sa venim cu noua distanta
C[!cc][q0++] = (punct) { x, y };
D[x][y] = D [C[cc][p].x][C[cc][p].y] + 1;
}
}
}
q = q0; q0 = 0;
cc = !cc;
}
}
void lee2() {
int x, y;
while (q) {
for (int p=0; p<q; ++p) {
for (int i=0; i<4; ++i) {
x=C[cc][p].x + dx[i], y = C[cc][p].y + dy[i];
if (A[x][y] && A[x][y] != '*' &&
greater<int>()(min(M [C[cc][p].x][C[cc][p].y], D[x][y]), M[x][y])) {
// e mai mare distanta minima din tot lantul parcurs..deci go for it..
C[!cc][q0++] = (punct) { x, y };
M[x][y] = min(M [C[cc][p].x][C[cc][p].y], D[x][y]);
}
}
}
q = q0; q0 = 0;
cc = !cc;
}
}
void part1()
{
int i, j;
freopen(FIN, "r", stdin);
freopen(FOUT,"w",stdout);
scanf("%d %d\n", &n, &m);
// *=perete, .=loc liber de camping, D=dragon, I=de unde pleaca prostu, O=target
memset(D, INF, sizeof(D));
for (i=1; i<=n; ++i) {
for (j=1; j<=m; ++j) {
scanf("%c", &A[i][j]);
if (A[i][j] == 'I')
st = (punct) { i, j };
else if (A[i][j] == 'O')
fin = (punct) { i, j };
else if (A[i][j] == 'D')
C[cc][q++] = (punct) { i, j }, D[i][j] = 0;
}
scanf("\n");
}
}
int main()
{
part1();
lee(std::less<int>());
// cand eftemie a ajuns pe poz (i, j), M[i][j] = min D[ik][jk] dp fiecare
// casuta parcursa pana acolo. M[fin.x][fin.y] tre sa fie max...
M[fin.x][fin.y] = -1;
C[cc=0][q++] = st; M[st.x][st.y] = D[st.x][st.y];
//lee2();
//printf("%d\n", M[fin.x][fin.y]);
return 0;
}