#include <iostream>
#include <fstream>
#include <queue>
#include <cmath>
using namespace std;
ifstream in("barbar.in");
ofstream out("barbar.out");
int dy[4]{1, -1, 0, 0}, dx[4]{0, 0, 1, -1};
int manhatt(int ay, int ax, int by, int bx) {return abs(ay-by)+abs(ax-bx);}
int mat[1001][1001], viz[1001][1001];
int ys, xs, yf, xf;
int minn=1000*1000;
struct coord
{
int y, x;
bool operator < (const coord other) const
{
if(mat[y][x]==mat[other.y][other.x]) return manhatt(y, x, yf, xf)>manhatt(other.y, other.x, yf, xf);
return mat[y][x]<mat[other.y][other.x];
}
};
queue <coord> lq;
priority_queue <coord> pq;
coord prev[1001][1001];
int n, m;
char rd;
bool isValid(coord pos) {return pos.y>0 && pos.x>0 && pos.y<=n && pos.x<=m;}
void coutmat(int mat[][1001])
{
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
cout<<mat[i][j]<<' ';
cout<<'\n';
}
cout<<'\n';
}
void readit()
{
in>>n>>m;
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
{
in>>rd;
if(rd=='D') lq.push({i, j}), mat[i][j]=1;
else if(rd=='I') ys=i, xs=j, pq.push({ys, xs});
else if(rd=='O') yf=i, xf=j;
else if(rd=='*') mat[i][j]=-1;
}
}
void Lee()
{
coord now, nxt;
while(!lq.empty())
{
now=lq.front(), lq.pop();
for(int i=0; i<4; i++)
{
nxt=now, nxt.y+=dy[i], nxt.x+=dx[i];
if(isValid(nxt) && !mat[nxt.y][nxt.x])
mat[nxt.y][nxt.x]=mat[now.y][now.x]+1, lq.push(nxt);
}
}
}
void Astar()
{
coord now, nxt;
while(!pq.empty())
{
now=pq.top(), pq.pop();
if(now.y==yf && now.x==xf) return;
for(int i=0; i<4; i++)
{
nxt=now, nxt.y+=dy[i], nxt.x+=dx[i];
if(isValid(nxt) && mat[nxt.y][nxt.x]!=-1 && !viz[nxt.y][nxt.x])
pq.push(nxt), prev[nxt.y][nxt.x]=now, viz[nxt.y][nxt.x]=1;
}
}
}
void traceback()
{
coord nav={yf, xf};
while(nav.y!=ys || nav.x!=xs) minn=min(minn, mat[nav.y][nav.x]), nav=prev[nav.y][nav.x], viz[nav.y][nav.x]=2;
}
int main()
{
readit();
Lee();
Astar();
traceback();
out<<minn-1;
return 0;
}