#include <bits/stdc++.h>
#define fi first
#define se second
using namespace std;
ifstream in("barbar.in");
ofstream out("barbar.out");
const int CNST=1e4;
char ch[1005][1005];
int viz[1005][1005],Lee[1005][1005],dx[4],dy[4],n,m;
queue <pair <int,int>> q;
priority_queue <pair <int,pair <int,int>>> h;
void MakeDs(){
dx[1]=0;
dx[3]=0;
dx[0]=-1;
dx[2]=1;
dy[0]=0;
dy[2]=0;
dy[1]=1;
dy[3]=-1;
return;
}
bool IsInMatrix(int i,int j){
if (i<1 or n<i)
return 0;
if (j<1 or m<j)
return 0;
return 1;
}
bool IsWalkable(int i,int j){
if (ch[i][j]=='I' or ch[i][j]=='O' or ch[i][j]=='.') return 1;
return 0;
}
void Lee_Function() {
while (!q.empty()) {
int x=q.front().first,y=q.front().second;
q.pop();
for (int k=0;k<=3;k++) {
int nx=x+dx[k],ny=y+dy[k];
if (IsInMatrix(nx,ny)==1 and Lee[nx][ny]==CNST) {
Lee[nx][ny]=Lee[x][y]+1;
q.push({nx,ny});
}
}
}
return;
}
signed main()
{
ios::sync_with_stdio(false);
in.tie(NULL);
out.tie(NULL);
MakeDs();
in>>n>>m;
int ist=0,jst=0;
int ifn=0,jfn=0;
for (int i=1;i<=n;++i) {
for (int j=1;j<=m;++j) {
in>>ch[i][j];
Lee[i][j]=CNST;
if (!IsWalkable(i,j))
Lee[i][j]+=CNST;
if (ch[i][j]=='I') {
ist=i;
jst=j;
}
if (ch[i][j]=='O') {
ifn=i;
jfn=j;
}
}
}
for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j)
if (ch[i][j]=='D') {
q.push({i,j});
Lee[i][j]=0;
}
Lee_Function();
h.push({Lee[ist][jst],{ist,jst}});
viz[ist][jst]=1;
int ans=Lee[ist][jst];
bool loob=0;
while (!h.empty()) {
int x=h.top().se.fi,y=h.top().se.se;
ans=ans>Lee[x][y] ? Lee[x][y]:ans;
if (x==ifn and y==jfn) {
loob=1;
break;
}
h.pop();
for (int k=0;k<=3;++k) {
int nx = x+dx[k], ny = y+dy[k];
if (IsInMatrix(nx,ny) and IsWalkable(nx,ny)==1 and viz[nx][ny]==0) {
h.push({Lee[nx][ny],{nx,ny}});
viz[nx][ny]=1;
}
}
}
if (loob==0)
ans=-1;
out<<ans;
return 0;
}