#include <stdio.h>
#include <stdlib.h>
#define MAX_Q 1000000
#define Nadejde 1000
#define MAX_DIR 4
#define NIL -1
const int delta[MAX_DIR][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
typedef struct {
int l, c;
} pair;
int N, M;
int qhead, qtail;
pair start, finish;
pair queue[MAX_Q + 1];
int d[Nadejde + 2][Nadejde + 2];
char s[Nadejde + 2][Nadejde + 2];
pair boss[Nadejde + 2][Nadejde + 2];
void overFlow(int n, int m) {
int i, j;
for (i = 0; i <= n; i++) {
d[i][0] = d[i][m] = NIL;
}
for (j = 0; j <= m; j++) {
d[0][j] = d[n][j] = NIL;
}
}
pair make(int l, int c) {
pair tmp;
tmp.l = l;
tmp.c = c;
return tmp;
}
void enqueue(int l, int c, int dist) {
queue[qtail++] = make(l, c);
d[l][c] = dist;
}
void dequeue(int *l, int *c, int *dist) {
(*l) = queue[qhead].l;
(*c) = queue[qhead++].c;
(*dist) = d[(*l)][(*c)] + 1;
}
void init() {
int i, l, c, l0, c0, dist;
do {
dequeue(&l, &c, &dist);
for (i = 0; i < MAX_DIR; i++) {
l0 = l + delta[i][0];
c0 = c + delta[i][1];
if (!d[l0][c0]) {
enqueue(l0, c0, dist);
}
}
} while (qhead != qtail);
}
int equal(pair X, pair Y) {
return ((X.l == Y.l) && (X.c == Y.c));
}
pair find(pair u) {
pair r, next;
for (r = u; !equal(boss[r.l][r.c], r); r = boss[r.l][r.c]);
for (; !equal(boss[u.l][u.c], u); u = next) {
next = boss[u.l][u.c];
boss[u.l][u.c] = r;
}
return r;
}
void unify(pair u, pair v) {
pair ru = find(u), rv = find(v);
if (!equal(ru, rv)) {
boss[rv.l][rv.c] = ru;
}
}
void connect(pair loc) {
int i;
pair next;
for (i = 0; i < MAX_DIR; i++) {
next = make(loc.l + delta[i][0], loc.c + delta[i][1]);
if (d[next.l][next.c] >= d[loc.l][loc.c]) {
unify(loc, next);
}
}
}
int escaped() {
return equal(find(start), find(finish));
}
void fire() {
int i, j, dist;
for (i = qtail - 1; i >= 0;) {
dist = d[queue[i].l][queue[i].c];
//fprintf(stderr, "%d\n", dist);
for (j = i; d[queue[j].l][queue[j].c] == dist; j--) {
connect(queue[j]);
}
i = j;
if (escaped()) {
fprintf(stdout, "%d\n", dist - 1);
exit(0);
}
}
}
int main(void) {
int i, j;
FILE *f = fopen("barbar.in", "r");
fscanf(f, "%d %d", &N, &M);
for (i = 1; i <= N; i++) {
fscanf(f, "%s", s[i] + 1);
for (j = 1; j <= M; j++) {
boss[i][j] = make(i, j);
if (s[i][j] == 'I') {
start = make(i, j);
} else if (s[i][j] == 'O') {
finish = make(i, j);
} else if (s[i][j] == 'D') {
enqueue(i, j, 1);
} else if (s[i][j] == '*') {
d[i][j] = NIL;
}
}
}
fclose(f);
//fprintf(stderr, "start = (%d, %d) si finish = (%d, %d)\n", start.l, start.c, finish.l, finish.c);
overFlow(N + 1, M + 1);
init();
freopen("barbar.out", "w", stdout);
/*for (i = 0; i <= 0+N; i++) {
for (j = 0; j <= 0+M; j++) {
fprintf(stdout, "%d ", d[i][j]);
}
fprintf(stdout, "\n");
}
*/
fire();
//freopen("barbar.out", "w", stdout);
fclose(stdout);
/// Multumim Doamne!
puts("Doamne ajuta!");
return 0;
}