#include <iostream>
#include <fstream>
#include <bitset>
#include <queue>
#include <set>
#include <bitset>
using namespace std;
#define MAXN 1005
#define INF 0x3f3f3f3f
class heap{
private:
pair<int, pair<int, int> > a[MAXN];
int sz = 0;
# define father(x) (x >> 1)
# define left_son(x) (x << 1)
# define right_son(x) ((x << 1) + 1)
public:
heap() {};
void insert(pair<int, pair<int, int> > x) {
a[sz] = x;
int k = sz;
sz++;
while ((k > 0) && (a[k] < a[father(k)])) {
swap(a[k], a[father(k)]);
k = father(k);
}
}
pair<int, pair<int, int> > top() {
if (sz > 0) {
return a[0];
}
return make_pair(0, make_pair(0, 0));
}
void pop() {
sz--;
a[0] = a[sz];
int k = 0;
while (right_son(k) < sz && (a[k] > a[left_son(k)] || a[k] > a[right_son(k)])) {
if (a[left_son(k)] > a[right_son(k)]) {
swap(a[k], a[right_son(k)]);
k = right_son(k);
} else {
swap(a[k] , a[left_son(k)]);
k = left_son(k);
}
}
if (left_son(k) < sz && a[k] > a[left_son(k)]) {
swap(a[k] , a[left_son(k)]);
}
}
bool empty() {
if (sz == 0) {
return true;
}
return false;
}
int size() {
return sz;
}
};
FILE *f = fopen("barbar.in", "r");
FILE *g = fopen("barbar.out", "w");
int n, m, startx, starty, stopx, stopy, sol;
int a[MAXN][MAXN];
queue< pair<int, int> > q;
int d[4][2] = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
heap mst;
bitset<MAXN> viz[MAXN];
bool isvalid(int i, int j) {
if (1 <= i && i <= n && 1 <= j && j <= m && a[i][j] != -1) {
return true;
}
return false;
}
void lee1()
{
while (!q.empty()) {
int x = q.front().first;
int y = q.front().second;
q.pop();
for (int i = 0; i < 4; i++) {
int nx = x + d[i][0];
int ny = y + d[i][1];
if (isvalid(nx, ny) && a[nx][ny] > a[x][y] + 1) {
a[nx][ny] = a[x][y] + 1;
q.push(make_pair(nx, ny));
}
}
}
}
void lee2()
{
mst.insert(make_pair(-a[startx][starty], make_pair(startx, starty)));
sol = a[startx][starty];
while (!mst.empty()) {
int x = mst.top().second.first;
int y = mst.top().second.second;
mst.pop();
if (x == stopx && y == stopy) {
sol = min(sol, a[x][y]);
break;
}
if (viz[x][y] == true) {
continue;
}
viz[x][y] = true;
sol = min(sol, a[x][y]);
for (int i = 0; i < 4; i++) {
int nx = x + d[i][0];
int ny = y + d[i][1];
if (isvalid(nx, ny)) {
mst.insert(make_pair(-a[nx][ny], make_pair(nx, ny)));
}
}
}
}
int main()
{
fscanf(f, "%d %d\n", &n, &m);
char buf[MAXN];
for (int i = 1; i <= n; i++) {
fgets(buf + 1, sizeof(buf), f);
for (int j = 1; j <= m; j++) {
switch (buf[j]) {
case '.':
a[i][j] = INF;
break;
case 'D':
q.push(make_pair(i, j));
break;
case 'I':
startx = i;
starty = j;
a[i][j] = INF;
break;
case 'O':
stopx = i;
stopy = j;
a[i][j] = INF;
break;
case '*':
a[i][j] = -1;
break;
}
}
}
lee1();
lee2();
fprintf(g, "%d\n", sol);
fclose(f);
fclose(g);
return 0;
}