#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<vector<int>> matrix;
#define sx first
#define sy second
string file = "file";
ifstream f(file + ".in");
ofstream g(file + ".out");
ll n, m, xi, yi, xo, yo;
matrix v, dist, costs;
string s;
deque<pair<int, int>> d;
const int dx[] = { 0 , 0 , 1 , -1 }, dy[] = { 1 , -1 , 0 , 0 };
void test2d()
{
for (ll i = 1; i <= n; i++)
{
for (ll j = 1; j <= m; j++)
{
g << v[i][j] << " ";
}
g << endl;
}
g << endl;
for (ll i = 1; i <= n; i++)
{
for (ll j = 1; j <= m; j++)
{
g << dist[i][j] << " ";
}
g << endl;
}
g << endl;
for (ll i = 1; i <= n; i++)
{
for (ll j = 1; j <= m; j++)
{
g << costs[i][j] << " ";
}
g << endl;
}
g << endl;
}
void init()
{
f >> n >> m;
v.resize(n + 5);
dist.resize(n + 5);
costs.resize(n + 5);
v[0].resize(m + 5, -1);
dist[0].resize(m + 5, -1);
costs[0].resize(m + 5, -1);
for (ll i = 1; i <= n; i++)
{
v[i].resize(m + 5, -1);
dist[i].resize(m + 5, -1);
costs[i].resize(m + 5, -1);
f >> s;
for (ll j = 1; j <= m; j++)
{
char cs = s[j - 1];
if (cs == '.') v[i][j] = 1;
else if (cs == '*') v[i][j] = 2;
else if (cs == 'D') v[i][j] = 3, d.push_back({ i, j });
else if (cs == 'I') v[i][j] = 1, xi = i, yi = j;
else if (cs == 'O') v[i][j] = 1, xo = i, yo = j;
}
}
v[n + 1].resize(m + 5, -1);
dist[n + 1].resize(m + 5, -1);
costs[n + 1].resize(m + 5, -1);
}
void dragons()
{
while (d.size())
{
int x = d.front().sx, y = d.front().sy;
if (dist[x][y] == -1 && v[x][y] == 3) dist[x][y] = 0;
d.pop_front();
for (int k = 0; k < 4; k++)
{
ll nx = x + dx[k], ny = y + dy[k];
if (dist[nx][ny] == -1 && v[nx][ny] != -1)
{
dist[nx][ny] = dist[x][y] + 1;
d.push_back({ nx, ny });
}
else if (dist[nx][ny] > 0)
{
dist[nx][ny] = min(dist[nx][ny], dist[x][y] + 1);
}
}
}
}
void path()
{
costs[xi][yi] = dist[xi][yi];
d.push_back({ xi, yi });
while (d.size())
{
int x = d.front().sx, y = d.front().sy;
d.pop_front();
//g << x << " " << y << " " << dist[x][y] << " " << minn << endl;
for (int k = 0; k < 4; k++)
{
ll nx = x + dx[k], ny = y + dy[k];
if (v[x][y] == v[nx][ny] && costs[nx][ny] == -1)
{
if (costs[x][y] <= dist[nx][ny])
{
costs[nx][ny] = costs[x][y];
d.push_front({ nx, ny });
}
else if (costs[x][y] > dist[nx][ny])
{
costs[nx][ny] = dist[nx][ny];
d.push_back({ nx, ny });
}
}
}
}
}
int main()
{
init();
dragons();
path();
//test2d();
g << costs[xo][yo];
return 0;
}