#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string.h>
typedef long long int ll;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000001
using namespace std;

int H=19,W=15;

enum DIR{
    Left_Up,
    Up,
    Right_Up,
    Left,
    Right,
    Left_Down,
    Down,
    Right_Down,
};

DIR dir[8] = {Left_Up,Up,Right_Up,Left,Right,Left_Down,Down,Right_Down};

int diff_row[8] = {-1,-1,-1,0,0,1,1,1},diff_col[8] = {-1,0,1,-1,1,-1,0,1};

struct BlackStone{
    BlackStone(){
        row = col = 0;
    }

    BlackStone(short arg_row,short arg_col){
        row = arg_row;
        col = arg_col;
    }
    short row,col;
};

struct Info{
    vector<BlackStone> BLACK_STONE;
    short row,col,count;
};

bool rangeCheck(short row,short col){
    if(row <= 17){
        if(col < 0 || col > 14){
            return false;
        }else{
            return true;
        }
    }else{ //row >= 18
        if(row == 18 && (col < 0 || col > 14)){
            return false;
        }else{
            return true;
        }
    }
}

Info move(Info info,DIR dir){
    Info ret;

    char map[19][15];
    for(int i = 0; i < H; i++){
        for(int k = 0; k < W; k++)map[i][k] = '.';
    }

    for(int i = 0; i < info.BLACK_STONE.size(); i++){
        map[info.BLACK_STONE[i].row][info.BLACK_STONE[i].col] = 'X';
    }
    ret.count = info.count+1;

    int next_row,next_col,index;

    switch(dir){
    case Left_Up:
        index = 0;
        break;
    case Up:
        index = 1;
        break;
    case Right_Up:
        index = 2;
        break;
    case Left:
        index = 3;
        break;
    case Right:
        index = 4;
        break;
    case Left_Down:
        index = 5;
        break;
    case Down:
        index = 6;
        break;
    case Right_Down:
        index = 7;
        break;
    }

    next_row = info.row+diff_row[index];
    next_col = info.col+diff_col[index];

    while(rangeCheck(next_row,next_col) == true && map[next_row][next_col] == 'X'){
        next_row += diff_row[index];
        next_col += diff_col[index];
    }


    if(next_row == info.row+diff_row[index] && next_col == info.col+diff_col[index]){
        ret.row = 1;
        ret.col = -1;
    }else{

        if(rangeCheck(next_row,next_col) == true && next_row <= 18){ //???????????§??????????????¢??????????????´???

        	for(int i = 0; i < info.BLACK_STONE.size();i++){
        		ret.BLACK_STONE.push_back(info.BLACK_STONE[i]);
        	}

            int tmp_row,tmp_col;

            tmp_row = info.row+diff_row[index];
            tmp_col = info.col+diff_col[index];

            while(tmp_row != next_row || tmp_col != next_col){
                for(int i = 0; i < ret.BLACK_STONE.size();i++){
                    if(ret.BLACK_STONE[i].row == tmp_row && ret.BLACK_STONE[i].col == tmp_col){
                        ret.BLACK_STONE.erase(ret.BLACK_STONE.begin()+i);
                        break;
                    }
                }
                tmp_row += diff_row[index];
                tmp_col += diff_col[index];
            }
        }

        ret.row = next_row;
        ret.col = next_col;
    }

    return ret;
}

int main(){

    Info first;

    char buf[15];
    int minimum = BIG_NUM,start_row,start_col,num;
    bool FLG = true;

    for(short i = 0; i < H; i++){
        scanf("%s",buf);
        if(i == 17){
        	num = 0;
        }
        for(short k = 0; k < W; k++){
            if(buf[k] == 'O'){
                start_row = i;
                start_col = k;
            }else if(buf[k] == 'X'){
                first.BLACK_STONE.push_back(BlackStone(i,k));
            }
            if((i == 17 || i == 18) && buf[k] == 'X')num++;
        }
        if(i == 18 && num == 0){
        	FLG = false;
        }
    }

    if(!FLG){
    	printf("-1\n");
    	return 0;
    }

    first.row = start_row;
    first.col = start_col;
    first.count = 0;

    queue<Info> Q;
    Q.push(first);

    while(!Q.empty()){

        if(Q.front().row >= 18){
            minimum = Q.front().count;
            break;
        }else{

            for(int i = 0; i < 8; i++){
            	Info next = move(Q.front(),dir[i]);

                if(rangeCheck(next.row,next.col)){
                    Q.push(next);
                }
            }

            Q.pop();
        }
    }

    if(minimum == BIG_NUM){
        printf("-1\n");
    }else{
        printf("%d\n",minimum);
    }

    return 0;
}

Measured memory_bytes: 2752