#include <fstream>
#include <stdio.h>
#include <string.h>
using namespace std;
int N,M,K,res, q[1010*1010][2], dist[1010][1010], a[1010][1010], sx,sy, fx,fy;
bool vizitat[1010][1010];
void add(int x, int y, int l){
q[++K][0]=x;
q[K][1]=y;
dist[x][y]=l;
}
void add_cell(int x, int y){
q[++K][0]=x;
q[K][1]=y;
}
bool valid(int x, int y){
if (x<1 || x>N || y<1 || y>M || dist[x][y]!=0 || a[x][y]!=0 )
return 0;
return 1;
}
bool validDist(int x, int y, int k){
if (x<1 || x>N || y<1 || y>M || dist[x][y]<k || a[x][y]!=0 || vizitat[x][y]!=0)
return 0;
return 1;
}
void find_dist(void){
int start=1,l=1,i,aux,x,y;
while (start<=K){
aux=K;
for (i=start; i<=aux; i++){
x=q[i][0]; y=q[i][1];
if (valid(x+1,y)) add(x+1,y,l);
if (valid(x-1,y)) add(x-1,y,l);
if (valid(x,y+1)) add(x,y+1,l);
if (valid(x,y-1)) add(x,y-1,l);
}
l++;
start=aux+1;
}
}
bool check(int dis){
int start=1,i,aux,x,y;
K=1;
q[1][0]=sx; q[1][1]=sy;
if (!validDist(q[1][0],q[1][1],dis))
return 0;
while (start<=K){
aux=K;
for (i=start; i<=aux; i++){
x=q[i][0]; y=q[i][1];
vizitat[x][y]=1;
if (q[i][0]==fx && q[i][1]==fy)
return 1;
if (validDist(x+1,y,dis)) add_cell(x+1,y);
if (validDist(x-1,y,dis)) add_cell(x-1,y);
if (validDist(x,y+1,dis)) add_cell(x,y+1);
if (validDist(x,y-1,dis)) add_cell(x,y-1);
}
start=aux+1;
}
return 0;
}
int main(){
ifstream in("barbar.in");
ofstream out("barbar.out");
in >> N >> M;
int i,j; char c;
K=0;
for (i=1; i<=N; i++)
for (j=1; j<=M; j++){
in >> c;
if (c=='.' || c=='I' || c=='O')
a[i][j]=0;
else
a[i][j]=1;
if (c=='D'){
q[++K][0]=i;
q[K][1]=j;
}
else if (c=='I'){
sx=i; sy=j;
}
else if (c=='O'){
fx=i; fy=j;
}
}
find_dist();
int l=0,r=N+M,mid;
while (r-l>1){
memset(vizitat,0,sizeof(vizitat));
mid=(l+r)/2;
if (check(mid)) l=mid;
else r=mid-1;
}
memset(vizitat,0,sizeof(vizitat));
if (check(l+1)) l++;
if (l==0)
out << -1;
else
out << l;
return 0;
}