#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcount

#define INF INT_MAX/3
#define mod 1000000007

struct state{
  int S;
  int i,j;
  int d;
};

const int w=15;
const int h=19;
string s[22];
int idx[22][22];
int N=0;
int si,sj;
int dist[1<<21];

int di[]={-1,-1,-1,0,0,1,1,1};
int dj[]={-1,0,1,-1,1,-1,0,1};

int main(){
  rep(i,h)cin>>s[i];
  memset(idx,-1,sizeof(idx));
  rep(i,h)rep(j,w){
    if(s[i][j]=='X'){
      idx[i][j]=N++;
    }
    if(s[i][j]=='O'){
      si=i;sj=j;
    }
  }

  rep(i,1<<N)dist[i]=INF;
  queue<state> que;
  que.push((state){(1<<N)-1,si,sj,0});
  dist[(1<<N)-1]=0;
  while(que.size()){
    state cs=que.front(); que.pop();
    rep(dir,8){
      int ni=cs.i+di[dir],nj=cs.j+dj[dir];
      if(ni<0||ni>=h||nj<0||nj>=w)continue;
      if(idx[ni][nj]==-1||((cs.S>>idx[ni][nj])&1)==0)continue;
      vector<int> uidxs;
      while(ni>=0&&ni<h&&nj>=0&&nj<w&&idx[ni][nj]!=-1&&((cs.S>>idx[ni][nj])&1)){
        uidxs.push_back(idx[ni][nj]);
        ni+=di[dir];
        nj+=dj[dir];
      }
      if(ni==h||(ni==h-1&&nj>=0&&nj<w)){
        cout<<cs.d+1<<endl;
        return 0;
      }
      if(ni<0||nj<0||nj>=w)continue;
      int nxtS=cs.S;
      rep(i,uidxs.size())nxtS^=(1<<uidxs[i]);
      if(dist[nxtS]!=INF)continue;
      que.push((state){nxtS,ni,nj,cs.d+1});
      dist[nxtS]=cs.d+1;
    }
  }
  cout<<-1<<endl;
  return 0;
}


