#include <bits/stdc++.h>
using namespace std;
int harta[1005][1005],i,j,R,C,par[1005][1005],L1,C1,L2,C2,maxim=-1,st,dr,mij,bun=-1,x;
char c,a[1005][1005];
ifstream f("barbar.in");
ofstream g("barbar.out");
queue<pair<int,int>> q;
void creeare(){
int d,dx[]={-1,0,1,0},dy[]={0,1,0,-1},i1,j1,inou,jnou;
while(!q.empty()){
i1=q.front().first;
j1=q.front().second;
q.pop();
for(d=0;d<4;d++){
inou=i1+dx[d];
jnou=j1+dy[d];
if(inou>=1 && inou<=R && jnou>=1 && jnou<=C && a[inou][jnou]!='*' && harta[inou][jnou]==-1){
harta[inou][jnou]=harta[i1][j1]+1;
maxim=max(harta[inou][jnou],maxim);
q.push({inou,jnou});
}
}
}
}
bool parcurgere(int starti,int startj,int final1,int final2,int verif){
int d,dx[]={-1,0,1,0},dy[]={0,1,0,-1},i1,j1,inou,jnou;
queue<pair<int,int>> q1;
q1.push({starti,startj});
par[starti][startj]=0;
while(!q1.empty()){
i1=q1.front().first;
j1=q1.front().second;
q1.pop();
for(d=0;d<4;d++){
inou=i1+dx[d];
jnou=j1+dy[d];
if(inou>=1 && inou<=R && jnou>=1 && jnou<=C && harta[inou][jnou]>=verif && harta[inou][jnou]!=-1){
if(inou==L2 && jnou==C2){
return true;
}
if(par[inou][jnou]==-1){
par[inou][jnou]=par[i1][j1]+1;
q1.push({inou,jnou});
}
}
}
}
return false;
}
int main()
{
memset(harta,-1,sizeof(harta));
memset(par,-1,sizeof(par));
f>>R>>C;
for(i=1;i<=R;i++){
for(j=1;j<=C;j++){
f>>c;
a[i][j]=c;
}
}
for(i=1;i<=R;i++){
for(j=1;j<=C;j++){
if(a[i][j]=='D'){
harta[i][j]=0;
q.push({i,j});
}
if(a[i][j]=='I'){
L1=i;
C1=j;
}
if(a[i][j]=='O'){
L2=i;
C2=j;
}
}
}
creeare();
st=0;
dr=maxim;
while(st<=dr){
x=(st+dr)/2;
if(parcurgere(L1,C1,L2,C2,x)){
bun=max(bun,x);
st=x+1;
memset(par,-1,sizeof(par));
}
else{
dr=x-1;
}
}
g<<bun;
return 0;
} //cod la alta problema, o pun aici ca sa o iau mai incolo