#include<cstdio>
#include<queue>
#include<cstring>
#define MAXN 1010
using namespace std;
queue<pair<int,int> > Queue;
pair<int,int> start,finish;
int a[MAXN][MAXN],dragon[MAXN][MAXN],seen[MAXN][MAXN],n,m;
int line[4]={0,1,0,-1};
int column[4]={1,0,-1,0};
bool Valid(int l,int c){
if(l<1||l>n||c<1||c>m)
return false;
return true;
}
void Precompute(){
int l,c,k,newL,newC;
while(!Queue.empty()){
l=Queue.front().first;
c=Queue.front().second;
Queue.pop();
for(k=0;k<4;k++){
newL=l+line[k];
newC=c+column[k];
if(dragon[newL][newC]==-1&&Valid(newL,newC)==true){
dragon[newL][newC]=dragon[l][c]+1;
Queue.push(make_pair(newL,newC));
}
}
}
}
bool Check(int value){
int l,c,k,newL,newC;
memset(seen,0,sizeof(seen));
if(dragon[start.first][start.second]<value)
return false;
Queue.push(start);
seen[start.first][start.second]=1;
while(!Queue.empty()){
l=Queue.front().first;
c=Queue.front().second;
Queue.pop();
for(k=0;k<4;k++){
newL=l+line[k];
newC=c+column[k];
if(a[newL][newC]==0&&Valid(newL,newC)==true&&dragon[newL][newC]>=value&&seen[newL][newC]==0){
seen[newL][newC]=1;;
Queue.push(make_pair(newL,newC));
}
}
}
if(seen[finish.first][finish.second]==0)
return false;
return true;
}
int BinarySearch(){
int answer=-1,middle,left=1,right=m+n;
while(left<=right){
middle=(left+right)/2;
if(Check(middle)==true){
answer=middle;
left=middle+1;
}
else
right=middle-1;
}
return answer;
}
int main(){
freopen("barbar.in","r",stdin);
freopen("barbar.out","w",stdout);
int i,j;
char ch;
scanf("%d%d\n",&n,&m);
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
scanf("%c",&ch);
dragon[i][j]=-1;
if(ch=='.')
a[i][j]=0;
if(ch=='D'){
Queue.push(make_pair(i,j));
dragon[i][j]=0;
}
if(ch=='I')
start=make_pair(i,j);
if(ch=='O')
finish=make_pair(i,j);
if(ch=='*')
a[i][j]=-1;
}
scanf("%c",&ch);
}
Precompute();
printf("%d",BinarySearch());
return 0;
}