#include <bits/stdc++.h>
using namespace std;
ifstream f("barbar.in");
ofstream g("barbar.out");
const int N = 1024;
int n, m, xs, ys, xf, yf, answer = 0, viz[N][N], d[N][N], valid(int, int);
int dx[] = {0, 0, -1, 1};
int dy[] = {1, -1, 0, 0};
char c;
void Search(int, int, int);
queue <pair<int, int>> q;
vector <pair<int, int>> drag;
priority_queue<tuple<int,int,int>> pq;
int main()
{
f >> n >> m;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
{
f >> c;
if(c == 'I')
xs = i, ys = j;
else if(c == 'O')
xf = i, yf = j;
else if(c == '*')
d[i][j] = -1;
else if(c == 'D')
{
d[i][j] = 1, q.push({i, j});drag.push_back({i,j});
}
}
for(int i=1;i<=n;i++)
d[i][0]=d[i][m+1]=-1;
for(int j=1;j<=m;j++)
d[0][j]=d[n+1][j]=-1;
while(!q.empty())
{
int x, y;
tie(x, y) = q.front();
q.pop();
for(int i = 0; i < 4; i++)
{
int new_x = x + dx[i], new_y = y + dy[i];
if(d[new_x][new_y] == 0)
{
d[new_x][new_y] = d[x][y] + 1;
q.push({new_x, new_y});
}
}
}
answer=min(d[xf][yf],d[xs][ys]);
if(abs(xs-xf)+abs(ys-yf)==1)
{
g<<answer-1;
return 0;
}
for(auto it:drag)
d[it.first][it.second]=-1;
answer=d[xs][ys];
pq.push(make_tuple(d[xs][ys],xs,ys));d[xs][ys]=-2;
pq.push(make_tuple(d[xf][yf],xf,yf));d[xf][yf]=-3;
while(pq.size())
{
int dist, x, y, i, j;
tie(dist,x,y)=pq.top();
pq.pop();
answer=min(answer,dist);
for(int k = 0; k < 4; k++)
{
i=x+dx[k];
j=y+dy[k];
if(d[x][y]+d[i][j]==-5)
{
g<<answer-1<<'\n';
return 0;
}
if(d[i][j]>1)
{
pq.push(make_tuple(d[i][j],i,j));d[i][j]=d[x][y];
}
}
}
g << - 1;
return 0;
}
int valid(int x, int y)
{
if(x < 1 || x > n || y < 1 || y > m || d[x][y] == -1)
return 0;
return 1;
}