#include<fstream>
#include<queue>
using namespace std;
ifstream cin("barbar.in");
ofstream cout("barbar.out");
pair<int,int> dragoni[100001];
int n,m,distante,cnt,cntdrag,xstart,ystart,xfinal,yfinal,minim,sol,ok,dr1,dr2;
int a[1001][1001],b[1001][1001],c[1001][1001],dx[]={0,0,-1,1},dy[]={1,-1,0,0},viz[1001][1001];
pair<int,int> stiva1[1001],stiva2[1001];
bool inmat(int x, int y){
return x>=1&&x<=n&&y>=1&&y<=m;
}
void rmat(){
for(int i=1;i<=dr1;i++){
int xx=stiva1[i].first,yy=stiva1[i].second;
b[xx][yy]=0;
}
dr1=0;
}
void rmat2(){
for(int i=1;i<=dr2;i++){
int xx=stiva2[i].first,yy=stiva2[i].second;
viz[xx][yy]=0;
}
}
void lee(int xs, int ys){
queue<pair<int,int> >q;
b[xs][ys]=1;
q.push(make_pair(xs,ys));
while(!q.empty()){
int x=q.front().first,y=q.front().second;
q.pop();
for(int i=0;i<4;i++){
int xnou=dx[i]+x,ynou=dy[i]+y;
stiva1[++dr1].first=xnou,stiva1[dr1].second=ynou;
if(a[xnou][ynou]!=0&&inmat(xnou,ynou)&&b[xnou][ynou]==0){
b[xnou][ynou]=b[x][y]+1;
if(a[xnou][ynou]>0)
q.push(make_pair(xnou,ynou));
}
}
}
}
void lee2(){
queue<pair<int,int> > q;
q.push(make_pair(xstart,ystart));
viz[xstart][ystart]=1;
stiva2[++dr2].first=xstart,stiva2[dr2].second=ystart;
//cout<<ok<<" ";
while(!q.empty()&&!ok){
int x=q.front().first,y=q.front().second;
q.pop();
for(int i=0;i<4;i++){
int xnou=x+dx[i],ynou=dy[i]+y;
//cout<<"t"<<" "<<xnou<<" "<<ynou<<"\n";
if(inmat(xnou,ynou)&&a[xnou][ynou]&&!viz[xnou][ynou]){
// cout<<"t"<<" "<<xnou<<" "<<ynou<<"\n";
if(c[xnou][ynou]==9999999){
lee(xnou,ynou);
for(int j=1;j<=cntdrag;j++)
c[xnou][ynou]=min(c[xnou][ynou],b[dragoni[j].first][dragoni[j].second]-1);
rmat();
}
//cout<<xnou<<" "<<ynou<<"\n";
if(xnou==xfinal&&ynou==yfinal){
sol=minim;
ok=1;
if(ok)
break;
}
else if(c[xnou][ynou]>=minim){
q.push(make_pair(xnou,ynou));
viz[xnou][ynou]=1;
stiva2[++dr2].first=xnou,stiva2[dr2].second=ynou;
}
}
}
}
while(!q.empty())
q.pop();
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
c[i][j]=9999999;
char car;
cin>>car;
if(car=='*')
a[i][j]=0;
else if(car=='.')
a[i][j]=++cnt;
else if(car=='D'){
dragoni[++cntdrag].first=i;
a[i][j]=-1;
dragoni[cntdrag].second=j;
}
else if(car=='I'){
xstart=i,ystart=j;
}
else{
xfinal=i,yfinal=j;
a[i][j]=++cnt;
}
}
lee(xstart,ystart);
for(int i=1;i<=cntdrag;i++)
c[xstart][ystart]=min(c[xstart][ystart],b[dragoni[i].first][dragoni[i].second]-1);
rmat();
lee(xfinal,yfinal);
for(int i=1;i<=cntdrag;i++)
c[xfinal][yfinal]=min(c[xfinal][yfinal],b[dragoni[i].first][dragoni[i].second]-1);
rmat();
int maxi=max(c[xfinal][yfinal],c[xstart][ystart]);
int st=1,dr=maxi;
while(st<=dr){
ok=0;
minim=(st+dr)/2;
//cout<<minim<<"\n";
lee2();
rmat2();
if(ok)
st=minim+1;
else
dr=minim-1;
}
//cout<<xstart<<ystart<<"\n";
//cout<<c[xstart][ystart];
cout<<sol;
}