#include <fstream>
#include <queue>
#include <bitset>
#include <cstdio>
#include <cstring>
#define N 1010
#define INF 9999999
#define PI pair<int, int>
#define x first
#define y second
#define mp make_pair
using namespace std;
FILE* fin=fopen("barbar.in","r");
FILE* fout=fopen("barbar.out","w");
const int maxb=8192;
char buf[maxb];
int ptr=0;
inline int getint() {
int nr=0;
while(buf[ptr]<'0'||'9'<buf[ptr])
if (++ptr>=maxb) fread(buf,maxb,1,fin),ptr=0;
while ('0'<=buf[ptr]&&buf[ptr]<='9') {
nr=nr*10+buf[ptr]-'0';
if (++ptr>=maxb) fread(buf,maxb,1,fin),ptr=0;
}
return nr;
}
inline char zgetchar()
{
char c;
while(buf[ptr]!='I' && buf[ptr]!='O' && buf[ptr]!='D' && buf[ptr]!='.' && buf[ptr]!='*')
if (++ptr>=maxb) fread(buf,maxb,1,fin),ptr=0;
c=buf[ptr];
if (++ptr>=maxb) fread(buf,maxb,1,fin),ptr=0;
return c;
}
int n,m,i,j,A[N][N],D[N][N],C[N][N],l1,c1,l2,c2,z;
char s;
queue<PI> Q;
bool InQue[N][N];
const int dx[4]={-1,0,1,0};
const int dy[4]={0,1,0,-1};
bool Ok1 (int i, int j, int l, int c)
{
if (l<1 || l>n || c<1 || c>m) return 0;
if (D[i][j]+1>=D[l][c]) return 0;
if (A[l][c]!=0) return 0;
return 1;
}
bool Ok2 (int i, int j, int l, int c)
{
if (l<1 || l>n || c<1 || c>m) return 0;
if (A[l][c]!=0) return 0;
if (min(D[l][c],C[i][j])<=C[l][c]) return 0;
return 1;
}
void Lee1 ()
{
while (!Q.empty())
{
i=Q.front().x;
j=Q.front().y;
Q.pop();
InQue[i][j]=0;
for (int d=0;d<4;d++)
if (Ok1(i,j,i+dx[d],j+dy[d]))
{
D[i+dx[d]][j+dy[d]]=D[i][j]+1;
if (!InQue[i+dx[d]][j+dy[d]])
{
Q.push(mp(i+dx[d],j+dy[d]));
InQue[i+dx[d]][j+dy[d]]=1;
}
}
}
}
bool Lee2 (int STOP)
{
memset(C,0,sizeof(C));
memset(InQue,0,sizeof(InQue));
Q.push(mp(l1,c1));
C[l1][c1]=D[l1][c1];
while (!Q.empty())
{
i=Q.front().x;
j=Q.front().y;
Q.pop();
InQue[i][j]=0;
for (int d=0;d<4;d++)
if (Ok2(i,j,i+dx[d],j+dy[d]))
{
if (min(C[i][j],D[i+dx[d]][j+dy[d]])<STOP) continue;
C[i+dx[d]][j+dy[d]]=min(C[i][j],D[i+dx[d]][j+dy[d]]);
if (!InQue[i+dx[d]][j+dy[d]])
{
Q.push(mp(i+dx[d],j+dy[d]));
InQue[i+dx[d]][j+dy[d]]=1;
}
if (i+dx[d]==l2 && j+dy[d]==c2) return 1;
}
}
return 0;
}
int Search ()
{
int p=1,u=D[l1][c1],ANS=-1,m;
while (p<=u)
{
m=(p+u)/2;
if (Lee2(m))
{
ANS=m;
p=m+1;
}
else u=m-1;
}
return ANS;
}
int main ()
{
n=getint();m=getint();
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
{
D[i][j]=INF;
C[i][j]=-1;
}
for (i=1;i<=n;i++)
{
for (j=1;j<=m;j++)
{
z=0;
s=zgetchar();
if (s=='*') z=-1;
if (s=='I')
{
l1=i;
c1=j;
}
if (s=='O')
{
l2=i;
c2=j;
}
if (s=='D')
{
z=-2;
Q.push(mp(i,j));
InQue[i][j]=1;
D[i][j]=0;
}
A[i][j]=z;
}
}
Lee1();
fprintf(fout,"%d\n",Search());
fclose(fin);fclose(fout);
return 0;
}