#include <bits/stdc++.h>
#define fi first
#define II inline
#define se second
#define pii pair <int, int>
#define FOR(i, a, b) for (int i = (a); i <= (b); i++)
using namespace std;
const int grid = 1002, INF = (int) 1e4 + 2;
char a[grid][grid], viz[grid][grid];
int dist[grid][grid];
pii paft; queue < pii > q;
II bool ispro (pii p, int N, int M){
return (p.fi > 0 && p.se > 0 && p.fi <= N && p.se <= M);
}
II void dp (int N, int M){
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};
for (; !q.empty(); q.pop()){
pii v = q.front();
for (int k = 0 ; k < 4 ; k++){
pii w = {v.fi + dx[k], v.se + dy[k]};
if (ispro(w, N, M) && dist[w.fi][w.se] > dist[v.fi][v.se] + 1 && a[w.fi][w.se] != '*'){
dist[w.fi][w.se] = dist[v.fi][v.se] + 1;
q.push(w);
}
}
}
}
II bool pos (int kthvalue, int N, int M){
if (dist[paft.fi][paft.se] < kthvalue)
return 0;
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};
memset(viz, 0, sizeof(viz));
q = queue < pii > ();
q.push({paft.fi, paft.se});
viz[paft.fi][paft.se] = 1;
for (; !q.empty(); q.pop()){
pii v = q.front();
if (a[v.fi][v.se] == 'O') return 1;
for (int k = 0 ; k < 4; k++){
pii w = {v.fi + dx[k], v.se + dy[k]};
if (ispro(w, N, M) && a[w.fi][w.se] != '*' && !viz[w.fi][w.se] && dist[w.fi][w.se] >= kthvalue){
viz[w.fi][w.se] = 1;
q.push(w);
}
}
}
return 0;
}
II int solve (int N, int M){
int left = 0, top = N * M, bstrez = -1;
while (left <= top){
int mid = left + ((top - left) >> 1 );
if (pos(mid, N, M))
left = mid + 1, bstrez = mid;
else top = mid - 1;
}
return bstrez;
}
int main(){
ifstream cin ("barbar.in");
ofstream cout ("barbar.out");
memset(dist, INF, sizeof(dist) );
int N, M;
cin >> N >> M;
FOR(i, 1, N)
FOR(j, 1, M){
cin >> a[i][j];
if (a[i][j] == 'D') q.push({i, j}), dist[i][j] = 0;
if (a[i][j] == 'I') paft = {i, j};
if (a[i][j] == '*') dist[i][j] = -1;
}
dp(N, M);
cout << solve(N, M);
return 0;
}