#include <stdio.h>
#define NMAX 2024
FILE *f = fopen("barbar.in","rt"), *g = fopen("barbar.out","wt");
struct pozc{long int x,y,cost;};
long int n,m,i,j,k,a[NMAX][NMAX],cost[NMAX][NMAX],hash[NMAX][NMAX];
pozc heap[NMAX*NMAX*2];
long int cd[NMAX*NMAX*2][2],dr,dimh,start[2],fin[2],st,nr;
long int dist[NMAX][NMAX];
void citire()
{char D[2048];
fscanf(f,"%ld %ld\n",&n,&m);
for (i=0;i<=n+1;i++)
{hash[i][m+1]=1;
hash[i][0]=1;}
for (i=0;i<=m+1;i++)
{hash[n+1][i]=1;
hash[0][i]=1;}
char c;
st=1;dr=0;
for (i=1;i<=n;i++)
{
fgets(D,m+3,f);
for (j=1;j<=m;j++)
{if (D[j-1]=='.') a[i][j]=0;
if (D[j-1]=='*') {a[i][j]=1;nr++;}
if (D[j-1]=='D') {cd[++dr][0]=i;cd[dr][1]=j;hash[i][j]=1;a[i][j]=0;}
if (D[j-1]=='I') {start[0]=i;start[1]=j;a[i][j]=0;}
if (D[j-1]=='O') {fin[0]=i;fin[1]=j;a[i][j]=0;}
}
}
}
int BF(long int c)
{long int i,final,x,y;
final=dr;
for (i=st;i<=dr;i++)
{cost[cd[i][0]][cd[i][1]]=c;
x=cd[i][0];y=cd[i][1];
if (!hash[x-1][y]&&(!a[x-1][y])) {cd[++final][0]=x-1;cd[final][1]=y;hash[x-1][y]=1;}
if (!hash[x][y-1]&&(!a[x][y-1])) {cd[++final][0]=x;cd[final][1]=y-1;hash[x][y-1]=1;}
if (!hash[x+1][y]&&(!a[x+1][y])) {cd[++final][0]=x+1;cd[final][1]=y;hash[x+1][y]=1;}
if (!hash[x][y+1]&&(!a[x][y+1])) {cd[++final][0]=x;cd[final][1]=y+1;hash[x][y+1]=1;}
}
if (final==dr) return 0;
st=dr+1;
dr=final;
return 1;
}
void addheap(long int x, long int y, long int c)
{
dimh++;
heap[dimh].x=x;
heap[dimh].y=y;
heap[dimh].cost=c;
long int i;
i=dimh;
pozc aux;
while (heap[i].cost>heap[i/2].cost&&i>1)
{aux=heap[i];
heap[i]=heap[i/2];
heap[i/2]=aux;
i/=2;}
}
void recheap(long int poz)
{
long int i,max;
pozc aux;
i=poz;
max=i;
if (heap[max].cost<heap[i*2].cost&&i*2<=dimh) max=i*2;
if (heap[max].cost<heap[i*2+1].cost&&i*2+1<=dimh) max=i*2+1;
if (max!=i)
{
aux=heap[i];
heap[i]=heap[max];
heap[max]=aux;
recheap(max);
}
}
void extract()
{
heap[1]=heap[dimh];
dimh--;
recheap(1);
}
long int MIN(long int a, long int b)
{
if (a>b) return b;
return a;
}
void djikstra()
{
long int i,x,y;
for (i=1;i<=n*m&&dimh;i++)
{x=heap[1].x;y=heap[1].y;
dist[x][y]=heap[1].cost;
extract();
if (!hash[x-1][y]&&(!a[x-1][y])) {addheap(x-1,y,MIN(dist[x][y],cost[x-1][y]));hash[x-1][y]=1;}
if (!hash[x+1][y]&&(!a[x+1][y])) {addheap(x+1,y,MIN(dist[x][y],cost[x+1][y]));hash[x+1][y]=1;}
if (!hash[x][y-1]&&(!a[x][y-1])) {addheap(x,y-1,MIN(dist[x][y],cost[x][y-1]));hash[x][y-1]=1;}
if (!hash[x][y+1]&&(!a[x][y+1])) {addheap(x,y+1,MIN(dist[x][y],cost[x][y+1]));hash[x][y+1]=1;}
}
}
void solve()
{long int ok;
ok=1;
st=1;
i=1;
while (ok)
{ok=BF(i-1);
i++;}
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
hash[i][j]=0;
dimh=1;
heap[1].x=start[0];
heap[1].y=start[1];
heap[1].cost=cost[start[0]][start[1]];
dist[fin[0]][fin[1]]=-1;
djikstra();
fprintf(g,"%ld",dist[fin[0]][fin[1]]);
}
int main()
{
citire();
solve();
fclose(f);
fclose(g);
return 0;
}