#include <cstdio>
#define min(a,b) (a<b)?a:b
#define max(a,b) (a>b)?a:b
#define INF 2000000000
#define NMAX 1002
using namespace std;
int Min,solpoz,st,n,m,ic,il,x,y,sol=-1,t[NMAX][NMAX],drag[NMAX][NMAX];
char s[NMAX][NMAX];bool ok[NMAX][NMAX];
int dx[]={0,0,-1,1};
int dy[]={-1,1,0,0};
struct coada{
int l,c,Min,poz;
}q[1000002],z;
void leedrag(short l,short c,int dist){
if(s[l][c]=='D'){Min=min(dist,Min);return ;}
if(dist>=Min) return ;
ok[l][c]=1;
for(short k=0;k<4;++k){
short l1=l+dx[k],c1=c+dy[k];
if(s[l1][c1]!='*'&&ok[l1][c1]==0&&l1>=0&&l1<n&&c1>=0&&c1<m)
{leedrag(l1,c1,dist+1);}
}ok[l][c]=0;
}
void lee(){
q[1].l=ic;q[1].c=il;
st=1;Min=INF;int ul=1;
leedrag(ic,il,0);
drag[ic][il]=Min;q[1].Min=Min;
while(st<=ul){
z=q[st];++st;
for(int k=0;k<4;++k){
short l=z.l+dx[k],c=z.c+dy[k];
if(l>=0&&l<n&&c>=0&&c<m&&s[l][c]!='*'&&drag[l][c]<drag[z.l][z.c]){
q[++ul].l=l,q[ul].c=c;
Min=q[st-1].Min;
leedrag(l,c,0);
q[ul].Min=Min;drag[l][c]=Min;
q[ul].poz=st-1;
if(l==x&&c==y){
sol=max(sol,Min);
solpoz=ul;
}
}
}
}
}
int main()
{
freopen("barbar.in", "r", stdin);
freopen("barbar.out", "w", stdout);
scanf("%d%d", &n, &m);
for(int i=0;i<n;++i)
scanf("%s", s[i]);
for(int i=0;i<n;++i)
for(int j=0;j<m;++j){
if(s[i][j]=='I')ic=j,il=i;
else if(s[i][j]=='O') x=i,y=j;
drag[i][j]=-1;
}
lee();
printf("%d", sol);
// while(solpoz>=1){
// printf("%d %d %d %d\n", q[solpoz].l,q[solpoz].c,q[solpoz].Min,solpoz);
// solpoz=q[solpoz].poz;
// }
return 0;
}