#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
#define Nmax 1005
#define INF 0x3f3f3f3f
using namespace std;
queue<pair<int,int> > Q;
char a[Nmax][Nmax];
char used[Nmax][Nmax];
int dist[Nmax][Nmax];
int DP[Nmax][Nmax];
int Sx,Sy,Ex,Ey;
int N,M;
const int dx[5]={0, 0,-1,0,1},
dy[5]={0,-1, 0,1,0};
void read()
{
scanf("%d%d",&N,&M);
for(int i = 1; i <= N; ++i){
scanf("%s",a[i]+1);
for(int j = 1; j <= M; ++j)
{
if(a[i][j] == 'I'){
Sx = i;
Sy = j;
a[i][j] = '.'; /// permitem trecerea
}
if(a[i][j] == 'O'){
Ex = i;
Ey = j;
a[i][j] = '.'; /// permitem trecerea
}
if(a[i][j] == 'D')
{
Q.push(make_pair(i,j));
dist[i][j] = 1;
}
}
a[i][0] = '#';
}
}
void sari(int x,int y,int k)
{
if(dist[x][y]) return;
dist[x][y] = k;
Q.push(make_pair(x,y));
}
void precalc()
{
int x,y,K,_x,_y;
while(!Q.empty())
{
x = Q.front().first;
y = Q.front().second;
K = dist[x][y];
Q.pop();
for(int i = 1; i <= 4; ++i)
{
_x = x + dx[i];
_y = y + dy[i];
if(a[_x][_y] != '.') continue;
sari(_x,_y,K+1);
}
}
/**for(int i = 1; i <= N; ++i,printf("\n\n"))
for(int j = 1; j <= M; ++j)
printf("%3d",dist[i][j]);
**/
}
int lee(int LIM)
{
memset(DP,0,sizeof(DP));
Q.push(make_pair(Sx,Sy));
DP[Sx][Sy] = 1;
int x,y,_x,_y;
while(!Q.empty())
{
x = Q.front().first;
y = Q.front().second;
Q.pop();
for(int i = 1; i <= 4; ++i)
{
_x = x + dx[i];
_y = y + dy[i];
if(a[_x][_y] != '.') continue;
if(dist[_x][_y] < LIM) continue;
if(DP[_x][_y]) continue;
DP[_x][_y] = 1;
Q.push(make_pair(_x,_y));
}
}
return DP[Ex][Ey];
}
void solve()
{
int li = 0,lf = dist[Sx][Sy],m;
while(li <= lf)
{
m = li + ((lf-li)>>1);
if(lee(m))
li = m + 1;
else
lf = m - 1;
}
if(lf == -1) ++ lf;
printf("%d\n",lf - 1);
}
int main()
{
freopen("barbar.in","r",stdin);
freopen("barbar.out","w",stdout);
read();
precalc();
solve();
return 0;
}