#include <cstdio>
#include <queue>
#include <cstring>
#define MAXN 1001
using namespace std;
queue < pair<int, int> > q;
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
bool wall[MAXN][MAXN], seen[MAXN][MAXN];
int n, m, dragonDistance[MAXN][MAXN], startX, startY, stopX, stopY;
inline bool ok(int x, int y)
{
if(x < 1 || x > n || y < 1 || y > m) return 0;
if(seen[x][y] || wall[x][y]) return 0;
return 1;
}
void dragonBFS()
{
int nextRow, nextCol, row, col, i;
while(!q.empty())
{
row = q.front().first;
col = q.front().second;
q.pop();
for(i=0; i<4; ++i)
{
nextRow = row + dx[i];
nextCol = col + dy[i];
if(ok(nextRow, nextCol))
{
dragonDistance[nextRow][nextCol] = dragonDistance[row][col] + 1;
seen[nextRow][nextCol] = 1;
q.push(make_pair(nextRow, nextCol));
}
}
}
}
bool bfs(int dist)
{
int nextRow, nextCol, i, row, col;
while(!q.empty()) q.pop();
memset(seen, 0, sizeof(seen));
q.push(make_pair(startX, startY));
seen[startX][startY] = 1;
if(dragonDistance[startX][startY] < dist)
return 0;
while(!q.empty())
{
row = q.front().first;
col = q.front().second;
q.pop();
for(i=0; i<4; ++i)
{
nextRow = row + dx[i];
nextCol = col + dy[i];
if(ok(nextRow, nextCol) && dragonDistance[nextRow][nextCol] >= dist)
{
seen[nextRow][nextCol] = 1;
q.push(make_pair(nextRow, nextCol));
if(nextRow == stopX && nextCol == stopY)
return 1;
}
}
}
return seen[stopX][stopY];
}
int main()
{
freopen("barbar.in", "r", stdin);
freopen("barbar.out", "w", stdout);
int i, j, pas = 1, ans = 0;
char c;
scanf("%d%d\n", &n, &m);
for(i=1; i<=n; ++i)
{
for(j=1; j<=m; ++j)
{
scanf("%c", &c);
if(c == '*') wall[i][j] = 1;
if(c == 'D') wall[i][j] = seen[i][j] = 1, q.push(make_pair(i, j));
if(c == 'I') startX = i, startY = j;
if(c == 'O') stopX = i, stopY = j;
}
scanf("%c", &c);
}
dragonBFS();
while((pas<<1) <= n && (pas<<1) <= m) pas<<=1;
for(; pas>=1; pas>>=1)
if(ans+pas<=n && ans+pas<=m && bfs(ans+pas))
ans += pas;
if(ans == 0){
printf("-1");
return 0;
}
printf("%d", ans);
return 0;
}