#include <stdio.h>
#include <cstring>
#include <queue>
#define nmax 1010
#define inf 0x3f3f3f3f
using namespace std;
int n,m,i,j,x,y,stx,sty,dist[nmax][nmax],dp[nmax][nmax],finx,finy;
queue < pair<int,int> > que,p;
char s[nmax][nmax]; bool good[nmax][nmax];
inline int min(int a,int b) { if (a<b) return a; else return b; }
int main() {
freopen("barbar.in","r",stdin);
freopen("barbar.out","w",stdout);
scanf("%d %d",&n,&m); gets(s[0]);
memset(dist,inf,sizeof(dist));
for (i=1;i<=n;i++) {
gets(s[i]+1);
for (j=1;j<=m;j++)
if (s[i][j]=='I') stx=i,sty=j; else
if (s[i][j]=='O') finx=i,finy=j; else
if (s[i][j]=='D') p.push(make_pair(i,j)),dist[i][j]=0; else
if (s[i][j]=='*') good[i][j]=true;
}
for (i=0;i<=n+1;i++) { good[i][0]=true; good[i][m+1]=true; }
for (i=0;i<=m+1;i++) { good[0][i]=true; good[n+1][i]=true; }
while (!p.empty()) {
x=p.front().first; y=p.front().second; p.pop();
if (dist[x][y]+1<dist[x+1][y] && !good[x+1][y]) {
dist[x+1][y]=dist[x][y]+1; p.push(make_pair(x+1,y));
}
if (dist[x][y]+1<dist[x][y+1] && !good[x][y+1]) {
dist[x][y+1]=dist[x][y]+1; p.push(make_pair(x,y+1));
}
if (dist[x][y]+1<dist[x-1][y] && !good[x-1][y]) {
dist[x-1][y]=dist[x][y]+1; p.push(make_pair(x-1,y));
}
if (dist[x][y]+1<dist[x][y-1] && !good[x][y-1]) {
dist[x][y-1]=dist[x][y]+1; p.push(make_pair(x,y-1));
}
}
que.push(make_pair(stx,sty)); dp[stx][sty]=dist[stx][sty];
while (!que.empty()) {
x=que.front().first; y=que.front().second; que.pop();
if (min(dp[x][y],dist[x+1][y])>dp[x+1][y] && !good[x+1][y]) {
dp[x+1][y]=min(dp[x][y],dist[x+1][y]); que.push(make_pair(x+1,y));
}
if (min(dp[x][y],dist[x][y+1])>dp[x][y+1] && !good[x][y+1]) {
dp[x][y+1]=min(dp[x][y],dist[x][y+1]); que.push(make_pair(x,y+1));
}
if (min(dp[x][y],dist[x-1][y])>dp[x-1][y] && !good[x-1][y]) {
dp[x-1][y]=min(dp[x][y],dist[x-1][y]); que.push(make_pair(x-1,y));
}
if (min(dp[x][y],dist[x][y-1])>dp[x][y-1] && !good[x][y-1]) {
dp[x][y-1]=min(dp[x][y],dist[x][y-1]); que.push(make_pair(x,y-1));
}
}
printf("%d",dp[finx][finy]);
return 0;
}