#include <iostream>
#include <fstream>
#include <deque>
using namespace std;
int dx[]={-1, 1, 0, 0};
int dy[]={0, 0, -1, 1};
char mat[1003][1003];
int r, c;
int BFSdragon(int startx, int starty) {
/**
deque<pair<int, int> > Q;
int ok=0, i, j, d, x, y, p, q, min=10000;
for(i=1; i<=r; i++) {
for(j=1; j<=c; j++) {
viz[i][j]=0;
}
}
//verificare
viz[startx][starty]=1;
Q.push_back(make_pair(startx, starty));
while(!Q.empty()) {
x=Q.front().first;
y=Q.front().second;
for(i=0; i<4; i++) {
p=x+dx[i];
q=y+dy[i];
if(viz[p][q]==0 && (mat[p][q]=='.' || mat[p][q]=='O')) {
viz[p][q]=viz[x][y]+1;
Q.push_back(make_pair(p, q));
}
if(mat[p][q]=='D') {
if(viz[x][y]+1<min) { min=viz[x][y]+1; }
}
}
Q.pop_front();
}
return min;
**/
//pastrez startx
int min=10000, i, d=10000;
if(mat[startx][starty]=='D') { return 0; }
for(i=starty-1; i>=1; i--) {
if(mat[startx][i]=='*') { break; }
if(mat[startx][i]=='D') {
d=starty-i;
if(d<min) { min=d; }
break;
}
}
for(i=starty+1; i<=c; i++) {
if(mat[startx][i]=='*') { break; }
if(mat[startx][i]=='D') {
d=i-starty;
if(d<min) { min=d; }
break;
}
}
//pastrez starty
for(i=startx-1; i>=1; i--) {
if(mat[i][starty]=='*') { break; }
if(mat[i][starty]=='D') {
d=startx-i;
if(d<min) { min=d; }
break;
}
}
for(i=startx+1; i<=r; i++) {
if(mat[i][starty]=='*') { break; }
if(mat[i][starty]=='D') {
d=i-startx;
if(d<min) { min=d; }
break;
}
}
return min;
}
int BFS(int startx, int starty, int endx, int endy, int dist) {
//dist = distanta minima pina la dragon ( > )
deque<pair<int, int> > Q;
int ok=0, i, j, d, x, y, p, q, mini;
char viz[1002][1002];
for(i=1; i<=r+1; i++) {
for(j=1; j<=c+1; j++) {
viz[i][j]=0;
}
}
//verificare
viz[startx][starty]=1;
Q.push_back(make_pair(startx, starty));
while(!Q.empty()) {
x=Q.front().first;
y=Q.front().second;
for(i=0; i<4; i++) {
ok=0;
p=x+dx[i];
q=y+dy[i];
mini=BFSdragon(p, q);
if(mini<dist) { ok=1; }
if(ok==0 && viz[p][q]==0 && (mat[p][q]=='D' || mat[p][q]=='.' || mat[p][q]=='O')) {
if(p==endx && q==endy) {
return 1;
}
viz[p][q]=1;
Q.push_back(make_pair(p, q));
}
}
Q.pop_front();
}
if(ok==1) { return 0; }
}
int cautabinar(int startx, int starty, int endx, int endy, int st, int dr) {
int mij, q;
while(st<=dr) {
mij=st+(dr-st)/2;
q=BFS(startx, starty, endx, endy, mij);
if(q==0) { dr=mij-1; }
else {
if(BFS(startx, starty, endx, endy, mij+1)==1) {
st=mij+1;
}
else { return mij; }
}
}
return -1;
}
int main() {
FILE *in=fopen("barbar.in", "r"), *out=fopen("barbar.out", "w");
int i, j, k, p, startx, starty, endx, endy;
//r linii, c coloane
fscanf(in, "%d%d\n", &r, &c);
for(i=1; i<=r; i++) {
for(j=1; j<=c; j++) {
fscanf(in, "%c", &mat[i][j]);
if(mat[i][j]=='I') { startx=i; starty=j; }
if(mat[i][j]=='O') { endx=i; endy=j; }
}
fscanf(in, "\n");
}
for(i=0; i<=r; i++) {
mat[0][i]='X'; mat[c+1][i]='X';
}
for(i=0; i<=c; i++) {
mat[i][0]='X'; mat[i][r+1]='X';
}
mat[r+1][c+1]='X';
//fprintf(out, "%d\n", cautabinar(startx, starty, endx, endy, 0, 1001));
long bl=0,br=r*c,bm;
while (br-bl>1)
{
bm=(bl+br)>>1;
if (BFS(startx, starty, endx, endy, bm)) bl=bm;
else br=bm;
}
if (bl) fprintf(out, "%ld\n",bl);
else
if(BFS(startx, starty, endx, endy, 0)) { fprintf(out, "0\n"); }
else { fprintf(out, "-1\n"); }
fclose(in); fclose(out);
//getch();
return 0;
}