//
// main.c
// barbar
//
// Created by Alexandru Bâgu on 1/13/14.
// Copyright (c) 2014 Alexandru Bâgu. All rights reserved.
//
#include <stdio.h>
#define MAX 1000
int M[MAX][MAX], Mn[MAX][MAX], V[MAX][MAX], Md[MAX][MAX];
typedef struct { int x, y; } COORD;
COORD Ds[MAX * MAX];
int ds = 0, end = 0;
int abs(int x) { if(x < 0) return -x; return x; }
int min(int a, int b) { if(a < b) return a; return b; }
int max(int a, int b) { if(a > b) return a; return b; }
int add_d(int x, int y)
{
Ds[ds].x = x;
Ds[ds].y = y;
ds++;
return 0;
}
int d_dist(int x, int y)
{
int i, _min = 10000;
for(i = 0; i < ds; i++)
_min = min(_min, abs(x - Ds[i].x) + abs(y - Ds[i].y));
return _min;
}
int avail(int a) { return a != -1 && a != -3; }
int lee(int,int);
int go_lee(int x, int y, int pDist)
{
if(!avail(M[x][y])) return 0;
if(M[x][y] == -2) end = 1;
if(V[x][y] == 0 || (V[x][y] == 1 && pDist > Md[x][y]))
{
V[x][y] = 1;
Md[x][y] = min(pDist, Mn[x][y]);
lee(x,y);
}
return 0;
}
int lee(int x, int y)
{
int d = Md[x][y];
go_lee(x, y - 1, d);
go_lee(x, y + 1, d);
go_lee(x - 1, y, d);
go_lee(x + 1, y, d);
return 0;
}
int main(int argc, const char * argv[])
{
freopen("barbar.in", "r", stdin);
freopen("barbar.out", "w", stdout);
int n, m, i, j, si, sj, ei, ej;
char x;
scanf("%d%d", &n, &m);
for(i = 0; i < MAX; i++)
for(j = 0; j < MAX; j++)
M[i][j] = -3, Mn[i][j] = 0, V[i][j] = 0;
for(i = 1; i <= n; i++)
{
for(j = 1; j <= m; j++)
{
do { scanf("%c", &x); } while (x == '\n');
if(x == '.') M[i][j] = 1;
else if(x == '*') M[i][j] = -1;
else if(x == 'I') { M[i][j] = 0; si =i; sj = j; }
else if(x == 'D') { add_d(i,j); M[i][j] = 1000; }
else if(x == 'O') { M[i][j] = -2; ei = i; ej = j; }
}
}
for(i = 1; i <= n; i++)
for(j = 1; j <= m; j++)
Mn[i][j] = d_dist(i,j);
Md[si][sj] = Mn[si][sj];
lee(si, sj);
/*for(i = 0; i <= n + 1; i++) {
for(j = 0; j <= n + 1; j++)
printf("%d ", Md[i][j]);
printf("\n");
}*/
printf("%d", Md[ei][ej]);
return 0;
}