//kdtree
/*#include<bits/stdc++.h>
#define N 200005
using namespace std;
vector<int> G[N];
int n,k,h[N],ans=0;
void dfs(int x,int pred)
{
vector<int> heights;
for(auto& i:G[x])
{
if(i!=pred)
{
dfs(i,x);
heights.push_back(h[i]+1);
}
}
if(heights.empty())
return;
sort(heights.begin(),heights.end());
int l=heights.size()-1;
//cout<<x<<' '<<l<<'\n';
while(l>0 && heights[l]+heights[l-1]>k)
{
++ans;
--l;
}
if(heights[0]>k){
heights.clear();
++ans;
h[x]=0;
}
else
{
h[x]=heights[l];
}
}
int main()
{
freopen("kdtree.in", "r", stdin);
freopen("kdtree.out", "w", stdout);
scanf("%d %d\n",&n,&k);
for(int i=1;i<n;++i){
int x,y;
scanf("%d %d\n",&x,&y);
G[x].emplace_back(y);
G[y].emplace_back(x);
}
dfs(1,-1);
cout<<ans;
}*/
#include<bits/stdc++.h>
#define pii pair<int,int>
#define mp make_pair
#define N 1005
#define Dim (int)1e9
using namespace std;
ifstream fin("barbar.in");
ofstream fout("barbar.out");
int dx[] = {1,-1,0,0};
int dy[] = {0,0,1,-1};
int n,m,sx,sy,fx,fy;
char a[N][N];
int dragons[N][N],viz[N][N];
bool valid(int x,int y)
{
return (x>=0 && x<n && y>=0 && y<m);
}
void read()
{
fin>>n>>m;
//memset(dragons,Dim,sizeof(dragons));
queue<pii> q;
for(int i=0;i<n;++i)
for(int j=0;j<m;++j)
dragons[i][j]=Dim;
for(int i=0;i<n;++i)
{
string s;
fin>>s;
for(int j=0;j<m;++j)
{
a[i][j]=s[j];
//cerr<<a[i][j];
if(s[j]=='D')
{
q.push(mp(i,j));
dragons[i][j]=0;
}
if(s[j]=='I')
{
sx=i;
sy=j;
}
if(s[j]=='O')
{
fx=i;
fy=j;
}
}
//cerr<<endl;
}
//fac multibfs din dragoni
while(!q.empty())
{
pii curr=q.front();
q.pop();
for(int i=0;i<4;++i)
{
int x1=curr.first+dx[i];
int y1=curr.second+dy[i];
if(!valid(x1,y1))
continue;
if(dragons[x1][y1]!=Dim)
continue;
if(a[x1][y1]=='*')
continue;
dragons[x1][y1]=dragons[curr.first][curr.second]+1;
q.push(mp(x1,y1));
}
}
/*for(int i=0;i<n;++i){
for(int j=0;j<m;++j)
cerr<<dragons[i][j]<<' ';
cerr<<endl;
}*/
}
bool bfs(int d)
{
if(dragons[sx][sy]<d)
return false;
queue<pii> q;
q.push(mp(sx,sy));
memset(viz,0,sizeof(viz));
while(!q.empty())
{
pii curr=q.front();
q.pop();
for(int i=0;i<4;++i)
{
int x1=curr.first+dx[i];
int y1=curr.second+dy[i];
if(!valid(x1,y1))
continue;
if(dragons[x1][y1]<d)
continue;
if(a[x1][y1]=='*')
continue;
if(viz[x1][y1])
continue;
if(x1==fx && y1==fy)
return true;
q.push(mp(x1,y1));
viz[x1][y1]=1;
}
}
return false;
}
int bs(int st,int dr)
{
if(st<0)
return -1;
if(st<=dr)
{
int mid=(st+dr)>>1;
if(!bfs(mid))
return bs(st,mid-1);
if(bfs(mid) && !bfs(mid+1))
return mid;
else
return bs(mid+1,dr);
}
return -1;
}
int main()
{
read();
fout<<bs(0,n+m)<<'\n';
}