# include <bits/stdc++.h>
using namespace std;
# define x first
# define y second
# define db double
# define ll long long
# define pi 3.14159265359
# define rad(x) (x * pi / 180)
const int p_1[] = {1,-1};
const ll mod1 = 100000004987ll;
const int mod2 = 1e9 + 7;
const int mod3 = 666013;
const int mod4 = 997;
const int mod5 = 1000004123;
template < class T > inline T sqr(T x) {return x*x;}
template < class T > inline T min(T a,T b,T c) {return min(a,min(b,c));}
template < class T > inline T min(T a,T b,T c,T d) {return min(min(a,b),min(b,c));}
template < class T > inline T max(T a,T b,T c) {return max(a,max(b,c));}
template < class T > inline T max(T a,T b,T c,T d) {return max(max(a,b),max(b,c));}
template < class T > inline T det(T a,T b,T c,T d) {return a * c - b * d;}
template < class T > inline T det(T s[3][3])
{
return - s[0][0] * det(s[1][1],s[1][2],s[2][1],s[2][2]) + s[0][1] * det(s[1][0],s[1][2],s[2][0],s[2][2]) - s[0][2] * det(s[1][0],s[1][1],s[2][0],s[2][1]);
}
template < class T1 , class T2 , class T3 > inline T3 pow(T1 a,T2 b,T3 mod) {T3 ans = 1;while (b){if (b&1) ans = (1LL * ans * a) % mod;a = (1LL * a * a) % mod;b >>= 1;}return ans;}
template < class T > T phi(T n){T cnt = n,p = n,ans = n;for (T i = 2;i*i <= p;++i)if (!(cnt%i)){ans /= i;ans *= (i-1);while (!(cnt%i)) cnt /= i;}if (cnt > 1) ans /= cnt,ans *= (cnt - 1);return ans;}
template < class T > T f(T a,T b) {return a < b ? 0 : a / b + f(a / b);}
template < class T > T gcd(T a,T b) {return __gcd(a,b);}
class Reader {
public:
Reader(const string& filename):
m_stream(filename),
m_pos(kBufferSize - 1),
m_buffer(new char[kBufferSize]) {
next();
}
Reader& operator>>(int& value) {
value = 0;
while (current() < '0' || current() > '9')
next();
while (current() >= '0' && current() <= '9') {
value = value * 10 + current() - '0';
next();
}
return *this;
}
private:
const int kBufferSize = 32768;
char current() {
return m_buffer[m_pos];
}
void next() {
if (!(++m_pos != kBufferSize)) {
m_stream.read(m_buffer.get(), kBufferSize);
m_pos = 0;
}
}
ifstream m_stream;
int m_pos;
unique_ptr<char[]> m_buffer;
};
# define cnt(x,y) ((x - 1) * m + y)
const int dx[] = {1,-1,0,0};
const int dy[] = {0,0,1,-1};
queue < pair < int , int > > q;
char c[1024][1024];
int d[1024][1024];
vector < pair < int , int > > s[1 << 20];
int dp[1 << 20];
set < pair < int , int > > g;
int main(void)
{
int n,m;
ifstream fi("barbar.in");
ofstream fo("barbar.out");
fi>>n>>m;
for (int i = 1;i <= n;++i)
fi>>(c[i] + 1);
for (int i = 1;i <= n;++i)
for (int j = 1;j <= m;++j)
if (c[i][j] == 'D')
{
d[i][j] = 1;
q.push({i,j});
}
while (!q.empty())
{
pair < int , int > p = q.front();
q.pop();
for (int i = 0;i < 4;++i)
{
pair < int , int > nw = {p.x+dx[i],p.y+dy[i]};
if (0 < nw.x && nw.x <= n && 0 < nw.y && nw.y <= m && !d[nw.x][nw.y])
d[nw.x][nw.y] = d[p.x][p.y] + 1,q.push(nw);
}
}
for (int i = 1;i <= n;++i)
for (int j = 1;j <= m;++j) --d[i][j];
for (int i = 1;i <= n;++i)
for (int j = 1;j <= m;++j)
if (c[i][j] != '*')
{
for (int k = 0;k < 4;++k)
{
pair < int , int > nw = {i + dx[k],j + dy[k]};
if (c[nw.x][nw.y] != '*')
if (0 < nw.x && nw.x <= n && 0 < nw.y && nw.y <= m)
s[cnt(i,j)].push_back({cnt(nw.x,nw.y),d[i][j]});
}
}
int h = n * m;
int start,finish;
for (int i = 1;i <= n;++i)
for (int j = 1;j <= m;++j)
if (c[i][j] == 'I') start = cnt(i,j);
else
if (c[i][j] == 'O') finish = cnt(i,j);
dp[start] = d[(start - 1) / m + 1][((start - 1) % m) + 1];
g.insert({dp[start],start});
while (!g.empty())
{
int v = g.begin()->y;
g.erase(g.begin());
for (auto it : s[v])
if (dp[it.x] < min(dp[v],it.y))
dp[it.x] = min(dp[v],it.y),g.insert({dp[it.x],it.x});
}
return fo << dp[finish] << '\n',0;
}