#include <iostream>
#include <queue>
#include <algorithm>
#include <vector>
#define NMAX 1000
using namespace std;
FILE *fin, *fout ;
struct elem {
int x ;
int y ;
};
char mat [ NMAX + 1 ] [ NMAX + 1 ] ;
int distDr [ NMAX + 1 ] [ NMAX + 1 ] ;
int dist [ NMAX + 1 ] [ NMAX + 1 ] ;
int dirl [ 4 ] = {0, 1, 0, -1 } ;
int dirc [ 4 ] = {1, 0, -1, 0 } ;
vector <elem> drag ;
queue <elem> q ;
void initdist (int n, int m) {
int i, j ;
for (i = 0 ; i < n+1 ; i++ ) {
for (j = 0 ; j < n+1 ; j++ ) {
dist[i][j] = 0 ;
}
}
}
void bfsdrag (int n, int m) {
int i ;
for (i = 0 ; i < drag.size() ; i++ )
q.push({drag[i].x, drag[i].y}) ;
while (!q.empty()) {
for (int dir = 0 ; dir < 4 ; dir++ ) {
int frx = q.front().x + dirl[dir] ;
int fry = q.front().y + dirc[dir] ;
if ( (mat[frx][fry] == '.' || mat[frx][fry] == 'O' ) && distDr[frx][fry] == 0 ) {
distDr[frx][fry] = distDr[q.front().x][q.front().y] + 1 ;
q.push({frx, fry}) ;
}
}
q.pop() ;
}
}
void bfs (int n, int m, int xst, int yst, int val ) {
q.push({xst, yst}) ;
while (!q.empty()) {
for (int dir = 0 ; dir < 4 ; dir++ ) {
int frx = q.front().x + dirl[dir] ;
int fry = q.front().y + dirc[dir] ;
if ( (mat[frx][fry] == '.' || mat[frx][fry] == 'O' ) && dist[frx][fry] == 0 && distDr[frx][fry] >= val ) {
dist[frx][fry] = dist[q.front().x][q.front().y] + 1 ;
q.push({frx, fry}) ;
}
}
q.pop() ;
}
}
char verif (int n, int m, int xf, int yf, int xst, int yst, int val ) {
bfs(n, m, xst, yst, val) ;
//for (int i = 1 ; i <= n ; i++ ) {
// for (int j = 1 ; j <= m ; j++ ) {
// fprintf (fout, "%d ", dist[i][j] ) ;
// }
// fprintf (fout, "\n" ) ;
//}
// fprintf (fout, "\n\n\n" ) ;
if (dist[xf][yf] != 0 ) {
initdist(n, m) ;
return 1 ;
}
initdist(n, m) ;
return 0 ;
}
int main() {
fin = fopen ("barbar.in", "r" ) ;
fout = fopen ("barbar.out", "w" ) ;
int n, i, m, xst, yst, xf, yf, st, dr, mid, j ;
char c ;
fscanf (fin, "%d%d\n", &n, &m ) ;
for (i = 1 ; i <= n ; i++ ) {
for (j = 1 ; j <= m ; j++ ) {
c = fgetc(fin) ;
switch (c) {
case 'O' : {
xf = i ;
yf = j ;
break ;
}
case 'I' : {
xst = i ;
yst = j ;
break ;
}
case 'D' : {
drag.push_back({i, j}) ;
break ;
}
}
mat[i][j] = c ;
}
c = fgetc(fin) ; /// enter
}
bfsdrag(n, m) ;
st = 1 ;
dr = max (n, m) ;
while (st <= dr) {
mid = (st + dr) / 2 ;
if (verif(n, m, xf, yf, xst, yst, mid) == 1 )
st = mid + 1 ;
else
dr = mid - 1 ;
}
fprintf (fout, "%d", dr ) ;
return 0;
}