// https://infoarena.ro/problema/barbar
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
ifstream fin("barbar.in");
ofstream fout("barbar.out");
const pair<int,int> dir[4]={{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
int main() {
int n, m;
fin>>n>>m;
queue<pair<int,int>> dq;
vector<vector<char>> t(n+2, vector<char>(m+2));
vector<vector<int>> dep(n+2, vector<int>(m+2)), mini(n+2, vector<int>(m+2));
vector<vector<bool>> vis(n+2, vector<bool>(m+2,true));
int pl, pc, il, ic;
for (int i=1; i<=n; ++i) {
for (int j=1; j<=m; ++j) {
fin>>t[i][j];
vis[i][j] = false;
if (t[i][j]=='D') dq.push({i, j});
else if (t[i][j]=='I') pl=i, pc=j;
else if (t[i][j]=='O') il=i, ic=j;
}
}
while (!dq.empty()) {
int x=dq.front().first, y=dq.front().second;
dq.pop();
vis[x][y] = true;
for (auto d:dir) {
int l=x+d.first, c=y+d.second;
if (!vis[l][c]) {
dep[l][c] = dep[x][y]+1;
dq.push({l, c});
}
}
}
bool ok=false;
priority_queue<pair<int,int>> pq;
pq.push({pl, pc});
mini[pl][pc] = dep[pl][pc];
while (!pq.empty()) {
int x=pq.top().first, y=pq.top().second;
pq.pop();
vis[x][y] = true;
if (x==il && y==ic) {
ok = true;
continue;
}
for (auto d:dir) {
int l=x+d.first, c=y+d.second;
if ((t[l][c]=='.' || t[l][c]=='O') && mini[l][c]<min(dep[l][c], mini[x][y])) {
mini[l][c] = min(dep[l][c], mini[x][y]);
pq.push({l, c});
}
}
}
fout<<(ok?mini[il][ic]:-1);
}