#include <iostream>
#include <fstream>
#include <queue>
#define MAX 1010
#define x first
#define y second
using namespace std;
ifstream fin("barbar.in");
ofstream fout("barbar.out");
queue <pair <int, int> > D;
queue <int> qx, qy;
int d[MAX][MAX], mat[MAX][MAX], n, m, maxx=MAX, dr;
char c;
pair <int, int> st, fi;
const int dx[]={-1, 0, 0, 1}, dy[]={0, 1, -1, 0};
void lee_D(){
int a, b, aa, bb;
while(!D.empty()){
qx.push(D.front().x);
qy.push(D.front().y);
D.pop();
dr--;
d[D.front().x][D.front().y]=1;
while(!qx.empty()){
a=qx.front();
b=qy.front();
qx.pop();
qy.pop();
for(int k=0; k<4; ++k){
aa=a+dx[k];
bb=b+dy[k];
if(aa && bb && aa<=n && bb<=m && mat[aa][bb]!=-1 && d[aa][bb]>d[a][b]+1){
d[aa][bb]=d[a][b]+1;
qx.push(aa);
qy.push(bb);
if(dr==0)
maxx=min(maxx, d[aa][bb]);
}
}
}
}
}
bool lee(int val){
int a, b, aa, bb;
qx.push(st.x);
qy.push(st.y);
while(!qx.empty()){
a=qx.front();
b=qy.front();
qx.pop();
qy.pop();
for(int k=0; k<4; ++k){
aa=dx[k]+a;
bb=dy[k]+b;
if(aa && bb && aa<=n && bb<=m && mat[aa][bb]!=-1 && d[aa][bb]>=val && mat[aa][bb]!=val){
mat[aa][bb]=val;
qx.push(aa);
qy.push(bb);
}
}
}
if(mat[fi.x][fi.y]==val)
return 1;
return 0;
}
int caut(int s, int d, bool ok){
if(s>d && ok==1)
return d;
else{
if(s>d && ok==0)
return -1;
else{
int m=(s+d)/2;
ok=lee(m);
if(ok==1)
return caut(m+1,d,ok);
else
return caut(s,m-1,ok);
}
}
}
int main()
{
fin>>n>>m;
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j){
fin>>c;
if(c=='*')
mat[i][j]=-1;
else
mat[i][j]=0;
if(c=='D'){
D.push(make_pair(i,j));
dr++;
}
if(c=='I')
st=make_pair(i,j);
if(c=='O')
fi=make_pair(i,j);
d[i][j]=MAX;
}
lee_D();
fout<<caut(1,maxx,0);
return 0;
}