#include <fstream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
void step(char **m, char **check, int R, int C, int x, int y, int newx, int newy);
void ver(char **m, char **check, int R, int C, int x, int y);
void directie(int x, int y, int &newx, int &newy, int dir);
void peretificare(char **marcat, int R, int C, int numar);
void reset(char **m, int R, int C) {
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
m[i][j] = 0;
}
}
}
void freee(char **m, char **check, char ** marcat, int R) {
for (int i = 0; i < R; i++) {
free(m[i]);
free(check[i]);
free(marcat[i]);
}
free(m);
free(check);
free(marcat);
}
int main()
{
ifstream fin("barbar.in");
ofstream fout("barbar.out");
int R, C, dist, i_start, j_start, i_iesire, j_iesire;
char **m, **check, **marcat;
fin >> R >> C;
m = (char**) malloc(R * sizeof(char*));
check = (char**) malloc(R * sizeof(char*));
marcat = (char**) malloc(R * sizeof(char*));
for (int i = 0; i < R; i++) {
m[i] = (char*) malloc(C * sizeof(char));
check[i] = (char*) malloc(C * sizeof(char));
marcat[i] = (char*) malloc(C * sizeof(char));
}
reset(check, R, C);
reset(marcat, R, C);
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
fin >> m[i][j];
if (m[i][j] == 'I') {
i_start = i;
j_start = j;
m[i][j] = '.';
} else if (m[i][j] == 'O') {
i_iesire = i;
j_iesire = j;
m[i][j] = '.';
} else if (m[i][j] == '*') {
marcat[i][j] = 3;
}
}
}
check[i_start][j_start] = 1;
ver(marcat, check, R, C, i_start, j_start);
if (check[i_iesire][j_iesire] == 0) {
fout << -1;
freee(m, check, marcat, R);
return 0;
}
for (int i = 0; i < R; i++) {
for(int j = 0; j < C; j++) {
if (m[i][j] == 'D') {
marcat[i][j] = 1;
}
}
}
reset(check, R, C);
ver(marcat, check, R, C, i_start, j_start);
if (check[i_iesire][j_iesire] == 0) {
fout << 0;
freee(m, check, marcat, R);
return 0;
}
for (dist = 1; dist < max(R, C); dist++) {
peretificare(marcat, R, C, 2 - dist % 2);
reset(check, R, C);
if (marcat[i_start][j_start] == 0) {
check[i_start][j_start] = 1;
} else {
break;
}
ver(marcat, check, R, C, i_start, j_start);
if (check[i_iesire][j_iesire] != 1) {
break;
}
}
fout << dist;
freee(m, check, marcat, R);
fin.close();
fout.close();
return 0;
}
void step(char **marcat, char **check, int R, int C, int x, int y, int newx, int newy) {
if (check[newx][newy] == 0) {
if (marcat[newx][newy] != 0) {
check[newx][newy] = 2;
} else {
check[newx][newy] = 1;
ver(marcat, check, R, C, newx, newy);
}
}
}
void ver(char **marcat, char **check, int R, int C, int x, int y) {
if (x <= R - 2) {
step(marcat, check, R, C, x, y, x + 1, y);
}
if (y <= C - 2) {
step(marcat, check, R, C, x, y, x, y + 1);
}
if (x >= 1) {
step(marcat, check, R, C, x, y, x - 1, y);
}
if (y >= 1) {
step(marcat, check, R, C, x, y, x, y - 1);
}
}
void peretificare(char **marcat, int R, int C, int numar) {
int newx, newy;
for (int i = 0; i < R; i++) {
for(int j = 0; j < C; j++) {
if (marcat[i][j] == numar) {
for(int dir = 0; dir <= 3; dir++) {
directie(i, j, newx, newy, dir);
if (newx >= 0 && newy >= 0 && newx <= R - 1 && newy <= C - 1 && marcat[newx][newy] == 0) {
marcat[newx][newy] = 3 - numar;
}
}
}
}
}
}
void directie(int x, int y, int &newx, int &newy, int dir) {
if (dir == 0) {
newx = x - 1;
newy = y;
} else if (dir == 1) {
newx = x;
newy = y + 1;
} else if (dir == 2) {
newx = x + 1;
newy = y;
} else if (dir == 3) {
newx = x;
newy = y - 1;
}
}