#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
FILE *f = freopen( "barbar.in", "r", stdin );
FILE *g = freopen( "barbar.out", "w", stdout );
int n, m, a[1005][1005], b[1005][1005], maxD;
int sx, sy, fx, fy;
int dx[4] = { -1, 0, 1, 0};
int dy[4] = { 0, 1, 0, -1};
queue< pair<int,int> > q;
void Read()
{
char s[1005];
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i)
{
scanf("%s", s+1 );
for(int j = 1; j <= m; ++j)
{
if( s[j] == '.' )
a[i][j] = -1;
else
if( s[j] == '*' )
a[i][j] = -2;
else
if( s[j] == 'I' )
{
sx = i, sy = j;
a[i][j] = -1;
}
else
if( s[j] == 'O' )
{
fx = i, fy = j;
a[i][j] = -1;
}
else
q.push( {i,j} );
}
}
}
bool isOk (int x, int y)
{
return 0 < x && x <= n && 0 < y && y <= m && a[x][y] == -1;
}
void Distances()
{
while( !q.empty() )
{
pair<int,int> cell = q.front();
q.pop();
for( int i = 0; i <= 3; ++i )
if ( isOk( cell.x + dx[i], cell.y + dy[i]) )
{
a[cell.x + dx[i]][cell.y + dy[i]] = a[cell.x][cell.y] + 1;
q.push( {cell.x + dx[i], cell.y + dy[i]} );
maxD = max( maxD, a[cell.x + dx[i]][cell.y + dy[i]]);
}
}
}
bool isOkFill (int x, int y, int val)
{
return 0 < x && x <= n && 0 < y && y <= m && ( b[x][y] >= val || b[x][y] == -3 ) && b[x][y] != -1;
}
void Fill( int x, int y, int val)
{
b[x][y] = -1;
if( b[fx][fy] == -1 )
return;
if( isOkFill( x - 1, y, val ) )
Fill( x - 1, y, val );
if( isOkFill( x, y + 1, val ) )
Fill( x, y + 1, val );
if( isOkFill( x + 1, y, val ) )
Fill( x + 1, y, val );
if( isOkFill( x, y - 1, val ) )
Fill( x, y - 1, val );
}
bool There_is_a_Way( int val )
{
if( a[sx][sy] < val || a[fx][fy] < val )
return 0;
for( int i = 1; i <= n; ++i )
for( int j = 1; j <= m; ++j )
b[i][j] = a[i][j];
b[fx][fy] = -3;
Fill( sx, sy, val );
if( b[fx][fy] == -3)
return 0;
return 1;
}
void Solve_BS()
{
int pas = 1 << 20, r = 0;
while( pas )
{
if( r + pas <= maxD && There_is_a_Way( r + pas ) )
r += pas;
pas /= 2;
}
if( r )
printf( "%d\n", r );
else
printf( "-1\n");
}
int main()
{
Read();
Distances();
Solve_BS();
return 0;
}