Problem:
Problem E:
Sliding Block Puzzle
In sliding block puzzles, we repeatedly slide pieces (blocks) to open spaces within a frame to establish a goal placement of pieces.
A puzzle creator has designed a new puzzle by combining the ideas of sliding block puzzles and mazes. The puzzle is played in a rectangular frame segmented into unit squares. Some squares are pre-occupied by obstacles. There are a number of pieces placed in the frame, one 2 × 2 king piece and some number of 1 × 1 pawn pieces. Exactly two 1 × 1 squares are left open. If a pawn piece is adjacent to an open square, we can slide the piece there. If a whole edge of the king piece is adjacent to two open squares, we can slide the king piece. We cannot move the obstacles. Starting from a given initial placement, the objective of the puzzle is to move the king piece to the upper-left corner of the frame.
The following figure illustrates the initial placement of the fourth dataset of the sample input.
Figure E.1: The fourth dataset of the sample input.
Your task is to write a program that computes the minimum number of moves to solve the puzzle from a given placement of pieces. Here, one move means sliding either king or pawn piece to an adjacent position.
Input
The input is a sequence of datasets. The first line of a dataset consists of two integers
H
and
W
separated by a space, where
H
and
W
are the height and the width of the frame. The following
H
lines, each consisting of
W
characters, denote the initial placement of pieces. In those
H
lines, '
X
', '
o
', '
*
', and '
.
' denote a part of the king piece, a pawn piece, an obstacle, and an open square, respectively. There are no other characters in those
H
lines. You may assume that 3 ≤
H
≤ 50 and 3 ≤
W
≤ 50.
A line containing two zeros separated by a space indicates the end of the input.
Output
For each dataset, output a line containing the minimum number of moves required to move the king piece to the upper-left corner. If there is no way to do so, output
-1
.
Sample Input
3 3
oo.
oXX
.XX
3 3
XXo
XX.
o.o
3 5
.o*XX
oooXX
oooo.
7 12
oooooooooooo
ooooo*****oo
oooooo****oo
o**ooo***ooo
o***ooooo..o
o**ooooooXXo
ooooo****XXo
5 30
oooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooo
o***************************oo
XX.ooooooooooooooooooooooooooo
XX.ooooooooooooooooooooooooooo
0 0
Output for the Sample Input
11
0
-1
382
6807

Submitted solutions:

code_snippet: #include<cstdio>
#include<cstring>
#include<queue>
#include<iostream>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=60;
int n,m;
char mp[maxn][maxn];
const int cx[]={-1,-1,0,1,2,2,0,1};
const int cy[]={0,1,2,2,0,1,-1,-1};
struct ty
{
    int x,y,d,c;
    ty(int x=0,int y=0,int d=0,int c=0):x(x),y(y),d(d),c(c){}
    inline bool in_range()
    {
        return x>=0&&x<n&&y>=0&&y<m;
    }
    ty p1()
    {
        return ty(x+cx[d<<1],y+cy[d<<1],0,0);
    }
    ty p2()
    {
        return ty(x+cx[(d<<1)^1],y+cy[(d<<1)^1],0,0);
    }
    void putit()
    {
        printf("state:%d %d %d %d\n",x,y,d,c);
    }
}st,p1,p2;
const int dx[]={0,0,-1,1};
const int dy[]={1,-1,0,0};
int p2p(ty st,ty en,ty king)
{
    if (!st.in_range()) return inf;
    if (!en.in_range()) return inf;
    queue<ty> qq;
    bool vis[maxn][maxn];
    memset(vis,0,sizeof(vis));
    qq.push(st);
    st.c=0;
    vis[st.x][st.y]=1;
    while (!qq.empty())
    {
        ty now=qq.front();
        qq.pop();
        if (now.x==en.x&&now.y==en.y) return now.c;
        for (int i=0;i<4;i++)
        {
            ty exp(now.x+dx[i],now.y+dy[i],0,now.c+1);
            if (exp.in_range()&&mp[exp.x][exp.y]!='*'&&(exp.x<king.x||exp.x>king.x+1||exp.y<king.y||exp.y>king.y+1)&&!vis[exp.x][exp.y])
            {
                vis[exp.x][exp.y]=1;
                qq.push(exp);
            }
        }
    }
    return inf;
}
queue<ty> q;
int cost[maxn][maxn][4];
void BFS()
{
    memset(cost,-1,sizeof(cost));
    if (st.x==0&&st.y==0)
    {
        cost[0][0][0]=0;
        return;
    }
    for (int i=0;i<4;i++)
    {
        st.d=i;
        int c1=p2p(p1,st.p1(),st);
        int c2=p2p(p2,st.p2(),st);
        int c3=p2p(p2,st.p1(),st);
        int c4=p2p(p1,st.p2(),st);
        st.c=min(c1+c2,c3+c4);
        if (st.c<inf)
        {
            q.push(st);
            cost[st.x][st.y][st.d]=st.c;
        }
    }
    while (!q.empty())
    {
        ty now=q.front();
        q.pop();
        if (now.c!=cost[now.x][now.y][now.d]) continue;
        for (int i=0;i<4;i++)
        {
            ty exp=now;
            exp.d=i;
            int c1=p2p(now.p1(),exp.p1(),now);
            int c2=p2p(now.p2(),exp.p2(),now);
            int c3=p2p(now.p1(),exp.p2(),now);
            int c4=p2p(now.p2(),exp.p1(),now);
            exp.c=now.c+min(c1+c2,c3+c4);
            int &c=cost[exp.x][exp.y][exp.d];
            if (exp.c<inf&&(c==-1||exp.c<c))
            {
                c=exp.c;
                q.push(exp);
            }
        }
        ty exp;
        switch (now.d)
        {
            case 0:exp=ty(now.x-1,now.y,2,now.c+1);break;
            case 1:exp=ty(now.x,now.y+1,3,now.c+1);break;
            case 2:exp=ty(now.x+1,now.y,0,now.c+1);break;
            case 3:exp=ty(now.x,now.y-1,1,now.c+1);break;
        }
        if (exp.in_range())
        {
            int &c=cost[exp.x][exp.y][exp.d];
            if (c==-1||exp.c<c)
            {
                c=exp.c;
                q.push(exp);
            }
        }
    }
}
int main()
{
    while (~scanf("%d%d",&n,&m)&&(n||m))
    {
        for (int i=0;i<n;i++) scanf("%s",mp[i]);
        st.x=p1.x=-1;
        for (int i=0;i<n;i++)
            for (int j=0;j<m;j++)
                if (mp[i][j]=='X'&&st.x==-1)
                {
                    st.x=i;
                    st.y=j;
                    st.c=0;
                }
                else if (mp[i][j]=='.')
                {
                    if (p1.x==-1) p1.x=i,p1.y=j;
                    else p2.x=i,p2.y=j;
                }
        BFS();
        int ans=-1;
        for (int i=0;i<4;i++)
            if (ans==-1||(cost[0][0][i]!=-1&&cost[0][0][i]<ans))
                ans=cost[0][0][i];
        printf("%d\n",ans);
    }
    return 0;
}
accuracy: 1
time_ms: 750
memory_kb: 3620
final_rank: 8

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int dx[4] = {1,0,-1,0}, dy[4] = {0,1,0,-1};
int nx[4][2] = {{2,2},{0,1},{-1,-1},{0,1}}, ny[4][2] = {{0,1},{2,2},{0,1},{-1,-1}};

int main() {
while(1) {
    int N, M;
    cin >> N >> M;
    if (N == 0) return 0;
    int SX = inf, SY = inf;
    vector<pair<int,int>> Open;
    vector<vector<bool>> B(N,vector<bool>(M));
    rep(i,0,N) {
        rep(j,0,M) {
            char C;
            cin >> C;
            if (C == '*') B[i][j] = false;
            else B[i][j] = true;
            if (C == 'X') chmin(SX,i), chmin(SY,j);
            if (C == '.') Open.push_back({i,j});
        }
    }
    if (SX == 0 && SY == 0) {
        cout << 0 << endl;
        continue;
    }
    auto canput = [&](int i, int j) -> bool {
        if (i < 0 || i+1 >= N || j < 0 || j+1 >= M) return false;
        return B[i][j] && B[i][j+1] && B[i+1][j] && B[i+1][j+1];
    };
    auto canmove = [&](int i, int j, int k) -> bool {
        rep(l,0,2) {
            int ni = i + nx[k][l], nj = j + ny[k][l];
            if (ni < 0 || N <= ni || nj < 0 || M <= nj) return false;
            if (!B[ni][nj]) false;
        }
        return true;
    };
    auto MakeDist = [&](int i, int j) -> vector<vector<int>> {
        vector<vector<int>> DP(N,vector<int>(M,inf));
        if (!B[i][j]) return DP;
        DP[i][j] = 0;
        queue<pair<int,int>> Q;
        Q.push({i,j});
        while(!Q.empty()) {
            auto [CurX, CurY] = Q.front();
            Q.pop();
            rep(k,0,4) {
                int NX = CurX + dx[k], NY = CurY + dy[k];
                if (NX < 0 || N <= NX || NY < 0 || M <= NY) continue;
                if (!B[NX][NY]) continue;
                if (chmin(DP[NX][NY],DP[CurX][CurY]+1)) {
                    Q.push({NX,NY});
                }
            }
        }
        return DP;
    };
    vector Dist(N-1, vector(M-1, vector(4, vector<int>(4,inf))));
    vector ANS(N-1, vector(M-1, vector(4, inf)));
    rep(i,0,N-1) {
        rep(j,0,M-1) {
            if (!canput(i,j)) continue;
            rep(k,0,2) {
                rep(l,0,2) {
                    B[i+k][j+l] = false;
                }
            }
            rep(k,0,4) {
                if (!canmove(i,j,k)) continue;
                pair<int,int> P0 = {i+nx[k][0],j+ny[k][0]}, P1 = {i+nx[k][1],j+ny[k][1]};
                auto DP0 = MakeDist(P0.first,P0.second), DP1 = MakeDist(P1.first,P1.second);
                if (i == SX && j == SY) {
                    chmin(ANS[i][j][k], DP0[Open[0].first][Open[0].second] + DP1[Open[1].first][Open[1].second]);
                    chmin(ANS[i][j][k], DP0[Open[1].first][Open[1].second] + DP1[Open[0].first][Open[0].second]);
                }
                rep(l,0,4) {
                    if (!canmove(i,j,l)) continue;
                    if (k == l) {
                        Dist[i][j][k][l] = 0;
                        continue;
                    }
                    pair<int,int> Q0 = {i+nx[l][0],j+ny[l][0]}, Q1 = {i+nx[l][1],j+ny[l][1]};
                    chmin(Dist[i][j][k][l],DP0[Q0.first][Q0.second]+DP1[Q1.first][Q1.second]);
                    chmin(Dist[i][j][k][l],DP0[Q1.first][Q1.second]+DP1[Q0.first][Q0.second]);
                }
            }
            rep(k,0,2) {
                rep(l,0,2) {
                    B[i+k][j+l] = true;
                }
            }
        }
    }
    priority_queue<pair<int,tuple<int,int,int>>,vector<pair<int,tuple<int,int,int>>>,greater<pair<int,tuple<int,int,int>>>> PQ;
    rep(i,0,4) {
        if (ANS[SX][SY][i] < inf) {
            PQ.push({ANS[SX][SY][i],{SX,SY,i}});
        }
    }
    while(!PQ.empty()) {
        auto [D,TUPLE] = PQ.top();
        PQ.pop();
        auto [X,Y,Dir] = TUPLE;
        if (D > ANS[X][Y][Dir]) continue;
        if (chmin(ANS[X+dx[Dir]][Y+dy[Dir]][Dir^2], D+1)) {
            PQ.push({D+1,{X+dx[Dir],Y+dy[Dir],Dir^2}});
        }
        rep(i,0,4) {
            if (chmin(ANS[X][Y][i],D+Dist[X][Y][Dir][i])) {
                PQ.push({ANS[X][Y][i],{X,Y,i}});
            }
        }
    }
    int ANS2 = inf;
    rep(i,0,4) chmin(ANS2, ANS[0][0][i]);
    if (ANS2 == inf) cout << -1 << endl;
    else cout << ANS2 << endl;
}
}
accuracy: 1
time_ms: 740
memory_kb: 3736
final_rank: 13

code_snippet: #include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
const int dx2[4] = {-1, 0, 2, 1};
const int dy2[4] = {0, 2, 1, -1};

const int MAX_FIELD_SIZE = 60;
const int MAX_DIRECTIONS = 4;
const int INFINITE_DISTANCE = 999999;

struct aa {
  int x;
  int y;
  int turn;
};

struct bb {
  int kx;
  int ky;
  int opway;
  int turn;
};

class Compare {
public:
  bool operator()(const bb &l, const bb &r) { return l.turn > r.turn; }
};

int getdis(const vector<vector<int>> &field, const int fx, const int fy,
           const int gx, const int gy) {
  int ans = INFINITE_DISTANCE;
  queue<aa> que;
  vector<vector<int>> memo(field.size(), vector<int>(field[0].size(), INFINITE_DISTANCE));
  que.push(aa{fx, fy, 0});
  while (!que.empty()) {
    aa atop(que.front());
    que.pop();
    if (atop.x == gx && atop.y == gy) {
      ans = atop.turn;
      break;
    }
    for (int i = 0; i < MAX_DIRECTIONS; ++i) {
      const int nextx = atop.x + dx[i];
      const int nexty = atop.y + dy[i];
      if (!field[nexty][nextx]) {
        if (atop.turn + 1 < memo[nexty][nextx]) {
          memo[nexty][nextx] = atop.turn + 1;
          que.push(aa{nextx, nexty, atop.turn + 1});
        }
      }
    }
  }
  return ans;
}

int main() {
  int memo2[MAX_FIELD_SIZE][MAX_FIELD_SIZE][MAX_DIRECTIONS];
  while (1) {
    for (int i = 0; i < MAX_FIELD_SIZE; ++i) {
      for (int j = 0; j < MAX_FIELD_SIZE; ++j) {
        for (int k = 0; k < MAX_DIRECTIONS; ++k) {
          memo2[i][j][k] = INFINITE_DISTANCE;
        }
      }
    }
    int H, W;
    cin >> H >> W;
    if (!H)
      break;
    vector<vector<int>> field(H + 2, vector<int>(W + 2, true));
    priority_queue<bb, vector<bb>, Compare> que;
    {
      int kx = 99, ky = 99;
      int ox[2];
      int oy[2];
      int num = 0;
      for (int i = 0; i < H; ++i) {
        string st;
        cin >> st;
        for (int j = 0; j < W; ++j) {
          if (st[j] == 'X') {
            kx = min(kx, j + 1);
            ky = min(ky, i + 1);
            field[i + 1][j + 1] = false;
          } else if (st[j] == 'o') {
            field[i + 1][j + 1] = false;
          } else if (st[j] == '.') {
            field[i + 1][j + 1] = false;
            ox[num] = j + 1;
            oy[num] = i + 1;
            num++;
          }
        }
      }
      if (kx == 1 && ky == 1) {
        cout << 0 << endl;
        continue;
      }
      for (int way = 0; way < MAX_DIRECTIONS; ++way) {
        int amin = INFINITE_DISTANCE;
        bool ok = true;
        for (int op = 0; op < 2; ++op) {
          int atime = 0;
          for (int lu = 0; lu < 2; ++lu) {
            const int fx = ox[op ^ lu];
            const int fy = oy[op ^ lu];
            int gx = kx + dx2[way];
            int gy = ky + dy2[way];
            if (lu == 1) {
              gx += dx[(way + 1) % MAX_DIRECTIONS];
              gy += dy[(way + 1) % MAX_DIRECTIONS];
            }
            if (field[gy][gx])
              ok = false;
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[ky + ay][kx + ax] = true;
              }
            }
            atime += getdis(field, fx, fy, gx, gy);
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[ky + ay][kx + ax] = false;
              }
            }
          }
          amin = min(amin, atime);
        }
        if (!ok)
          continue;
        else {
          memo2[kx][ky][way] = amin;
          que.push(bb{kx, ky, way, amin});
        }
      }
    }
    int ans = -1;
    while (!que.empty()) {
      bb atop(que.top());
      que.pop();
      const int fkx = atop.kx;
      const int fky = atop.ky;
      const int fway = atop.opway;
      const int fturn = atop.turn;
      if (fkx == 1 && fky == 1) {
        ans = fturn;
        break;
      }
      for (int tway = 0; tway < MAX_DIRECTIONS; ++tway) {
        if (fway == tway)
          continue;
        int amin = INFINITE_DISTANCE;
        bool ok = true;
        for (int op = 0; op < 2; ++op) {
          int atime = 0;
          for (int lu = 0; lu < 2; ++lu) {
            int fx = fkx + dx2[fway];
            int fy = fky + dy2[fway];
            int gx = fkx + dx2[tway];
            int gy = fky + dy2[tway];
            if (lu == 1) {
              gx += dx[(tway + 1) % MAX_DIRECTIONS];
              gy += dy[(tway + 1) % MAX_DIRECTIONS];
            }
            if (op ^ lu) {
              fx += dx[(fway + 1) % MAX_DIRECTIONS];
              fy += dy[(fway + 1) % MAX_DIRECTIONS];
            }
            if (field[gy][gx])
              ok = false;
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[fky + ay][fkx + ax] = true;
              }
            }
            atime += getdis(field, fx, fy, gx, gy);
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[fky + ay][fkx + ax] = false;
              }
            }
          }
          amin = min(amin, atime);
        }
        if (!ok)
          continue;
        else {
          if (memo2[fkx][fky][tway] > fturn + amin) {
            memo2[fkx][fky][tway] = fturn + amin;
            que.push(bb{fkx, fky, tway, fturn + amin});
          }
        }
      }
      {
        const int nkx = fkx + dx[fway];
        const int nky = fky + dy[fway];
        const int nway = (fway + 2) % MAX_DIRECTIONS;
        if (memo2[nkx][nky][nway] > fturn + 1) {
          memo2[nkx][nky][nway] = fturn + 1;
          que.push(bb{nkx, nky, nway, fturn + 1});
        }
      }
    }
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 1090
memory_kb: 3512
final_rank: 9

code_snippet: #include <iostream>
#include <vector>
#include <queue>
#include <string>

const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
const int dx2[4] = {-1, 0, 2, 1};
const int dy2[4] = {0, 2, 1, -1};

struct aa {
  int x;
  int y;
  int turn;
};

int getdis(const std::vector<std::vector<int>> &field, const int fx, const int fy,
           const int gx, const int gy) {
  int ans = 999999;
  std::queue<aa> que;
  std::vector<std::vector<int>> memo(field.size(), std::vector<int>(field[0].size(), 999999));
  que.push(aa{fx, fy, 0});
  while (!que.empty()) {
    aa atop(que.front());
    que.pop();
    if (atop.x == gx && atop.y == gy) {
      ans = atop.turn;
      break;
    }
    for (int i = 0; i < 4; ++i) {
      const int nextx = atop.x + dx[i];
      const int nexty = atop.y + dy[i];
      if (!field[nexty][nextx]) {
        if (atop.turn + 1 < memo[nexty][nextx]) {
          memo[nexty][nextx] = atop.turn + 1;
          que.push(aa{nextx, nexty, atop.turn + 1});
        }
      }
    }
  }
  return ans;
}

struct bb {
  int kx;
  int ky;
  int opway;
  int turn;
};

class Compare {
public:
  bool operator()(const bb &l, const bb &r) { return l.turn > r.turn; }
};

int memo2[60][60][4];

int main() {
  while (1) {
    for (int i = 0; i < 60; ++i) {
      for (int j = 0; j < 60; ++j) {
        for (int k = 0; k < 4; ++k) {
          memo2[i][j][k] = 999999;
        }
      }
    }

    // Init variables here
    int H, W;
    std::cin >> H >> W;

    if (!H)
      break;

    std::vector<std::vector<int>> field(H + 2, std::vector<int>(W + 2, true));
    std::priority_queue<bb, std::vector<bb>, Compare> que;

    // Reduction scope of variables
    {
      int kx = 99, ky = 99;
      int ox[2];
      int oy[2];
      int num = 0;

      for (int i = 0; i < H; ++i) {
        std::string st;
        std::cin >> st;
        for (int j = 0; j < W; ++j) {
          if (st[j] == 'X') {
            kx = std::min(kx, j + 1);
            ky = std::min(ky, i + 1);
            field[i + 1][j + 1] = false;
          } else if (st[j] == 'o') {
            field[i + 1][j + 1] = false;
          } else if (st[j] == '.') {
            field[i + 1][j + 1] = false;
            ox[num] = j + 1;
            oy[num] = i + 1;
            num++;
          }
        }
      }

      if (kx == 1 && ky == 1) {
        std::cout << 0 << '\n';
        continue;
      }

      for (int way = 0; way < 4; ++way) {
        // Init variables here
        int amin = 999999;
        bool ok = true;

        for (int op = 0; op < 2; ++op) {
          int atime = 0;

          for (int lu = 0; lu < 2; ++lu) {
            const int fx = ox[op ^ lu];
            const int fy = oy[op ^ lu];
            int gx = kx + dx2[way];
            int gy = ky + dy2[way];

            if (lu == 1) {
              gx += dx[(way + 1) % 4];
              gy += dy[(way + 1) % 4];
            }

            if (field[gy][gx])
              ok = false;

            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[ky + ay][kx + ax] = true;
              }
            }

            atime += getdis(field, fx, fy, gx, gy);

            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[ky + ay][kx + ax] = false;
              }
            }
          }

          amin = std::min(amin, atime);
        }

        if (!ok)
          continue;
        else {
          memo2[kx][ky][way] = amin;
          que.push(bb{kx, ky, way, amin});
        }
      }
    }

    // Init variables here
    int ans = -1;

    while (!que.empty()) {
      bb atop(que.top());
      que.pop();

      const int fkx = atop.kx;
      const int fky = atop.ky;
      const int fway = atop.opway;
      const int fturn = atop.turn;

      if (fkx == 1 && fky == 1) {
        ans = fturn;
        break;
      }

      for (int tway = 0; tway < 4; ++tway) {
        if (fway == tway)
          continue;

        // Init variables here
        int amin = 999999;
        bool ok = true;

        for (int op = 0; op < 2; ++op) {
          int atime = 0;

          for (int lu = 0; lu < 2; ++lu) {
            int fx = fkx + dx2[fway];
            int fy = fky + dy2[fway];
            int gx = fkx + dx2[tway];
            int gy = fky + dy2[tway];

            if (lu == 1) {
              gx += dx[(tway + 1) % 4];
              gy += dy[(tway + 1) % 4];
            }

            if (op ^ lu) {
              fx += dx[(fway + 1) % 4];
              fy += dy[(fway + 1) % 4];
            }

            if (field[gy][gx])
              ok = false;

            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[fky + ay][fkx + ax] = true;
              }
            }

            atime += getdis(field, fx, fy, gx, gy);

            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[fky + ay][fkx + ax] = false;
              }
            }
          }

          amin = std::min(amin, atime);
        }

        if (!ok)
          continue;
        else {
          if (memo2[fkx][fky][tway] > fturn + amin) {
            memo2[fkx][fky][tway] = fturn + amin;
            que.push(bb{fkx, fky, tway, fturn + amin});
          }
        }
      }

      {
        const int nkx = fkx + dx[fway];
        const int nky = fky + dy[fway];
        const int nway = (fway + 2) % 4;

        if (memo2[nkx][nky][nway] > fturn + 1) {
          memo2[nkx][nky][nway] = fturn + 1;
          que.push(bb{nkx, nky, nway, fturn + 1});
        }
      }
    }

    std::cout << ans << '\n';
  }

  return 0;
}
accuracy: 1
time_ms: 1090
memory_kb: 3316
final_rank: 5

code_snippet: #include <iostream>
#include <vector>
#include <queue>
#include <string>
using namespace std;

const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
const int dx2[4] = {-1, 0, 2, 1};
const int dy2[4] = {0, 2, 1, -1};

struct aa {
  int x;
  int y;
  int turn;
};

int getdis(vector<vector<bool>> field, const int fx, const int fy,
           const int gx, const int gy) {
  int ans = 999999;
  queue<aa> que;
  vector<vector<int>> memo(field.size(), vector<int>(field[0].size(), 999999));
  que.push(aa{fx, fy, 0});
  while (!que.empty()) {
    aa atop(que.front());
    que.pop();
    if (atop.x == gx && atop.y == gy) {
      ans = atop.turn;
      break;
    }
    for (int i = 0; i < 4; ++i) {
      const int nextx = atop.x + dx[i];
      const int nexty = atop.y + dy[i];
      if (!field[nexty][nextx]) {
        if (atop.turn + 1 < memo[nexty][nextx]) {
          memo[nexty][nextx] = atop.turn + 1;
          que.push(aa{nextx, nexty, atop.turn + 1});
        }
      }
    }
  }
  return ans;
}

struct bb {
  int kx;
  int ky;
  int opway;
  int turn;
};

class Compare {
public:
  bool operator()(const bb &l, const bb &r) { return l.turn > r.turn; }
};

int memo2[60][60][4];

int main() {
  while (1) {
    for (int i = 0; i < 60; ++i) {
      for (int j = 0; j < 60; ++j) {
        for (int k = 0; k < 4; ++k) {
          memo2[i][j][k] = 999999;
        }
      }
    }
    int H, W;
    cin >> H >> W;
    if (!H)
      break;
    vector<vector<bool>> field(H + 2, vector<bool>(W + 2, true));
    priority_queue<bb, vector<bb>, Compare> que;
    {
      int kx = 99, ky = 99;
      int ox[2];
      int oy[2];
      int num = 0;
      for (int i = 0; i < H; ++i) {
        string st;
        cin >> st;
        for (int j = 0; j < W; ++j) {
          if (st[j] == 'X') {
            kx = min(kx, j + 1);
            ky = min(ky, i + 1);
            field[i + 1][j + 1] = false;
          } else if (st[j] == 'o') {
            field[i + 1][j + 1] = false;
          } else if (st[j] == '.') {
            field[i + 1][j + 1] = false;
            ox[num] = j + 1;
            oy[num] = i + 1;
            num++;
          }
        }
      }
      if (kx == 1 && ky == 1) {
        cout << 0 << endl;
        continue;
      }
      for (int way = 0; way < 4; ++way) {
        int amin = 999999;
        bool ok = true;
        for (int op = 0; op < 2; ++op) {
          int atime = 0;
          for (int lu = 0; lu < 2; ++lu) {
            const int fx = ox[op ^ lu];
            const int fy = oy[op ^ lu];
            int gx = kx + dx2[way];
            int gy = ky + dy2[way];
            if (lu == 1) {
              gx += dx[(way + 1) % 4];
              gy += dy[(way + 1) % 4];
            }
            if (field[gy][gx])
              ok = false;
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[ky + ay][kx + ax] = true;
              }
            }
            atime += getdis(field, fx, fy, gx, gy);
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[ky + ay][kx + ax] = false;
              }
            }
          }
          amin = min(amin, atime);
        }
        if (!ok)
          continue;
        else {
          memo2[kx][ky][way] = amin;
          que.push(bb{kx, ky, way, amin});
        }
      }
    }
    int ans = -1;
    while (!que.empty()) {
      bb atop(que.top());
      que.pop();
      const int fkx = atop.kx;
      const int fky = atop.ky;
      const int fway = atop.opway;
      const int fturn = atop.turn;
      if (fkx == 1 && fky == 1) {
        ans = fturn;
        break;
      }
      for (int tway = 0; tway < 4; ++tway) {
        if (fway == tway)
          continue;
        int amin = 999999;
        bool ok = true;
        for (int op = 0; op < 2; ++op) {
          int atime = 0;
          for (int lu = 0; lu < 2; ++lu) {
            int fx = fkx + dx2[fway];
            int fy = fky + dy2[fway];
            int gx = fkx + dx2[tway];
            int gy = fky + dy2[tway];
            if (lu == 1) {
              gx += dx[(tway + 1) % 4];
              gy += dy[(tway + 1) % 4];
            }
            if (op ^ lu) {
              fx += dx[(fway + 1) % 4];
              fy += dy[(fway + 1) % 4];
            }
            if (field[gy][gx])
              ok = false;
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[fky + ay][fkx + ax] = true;
              }
            }
            atime += getdis(field, fx, fy, gx, gy);
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[fky + ay][fkx + ax] = false;
              }
            }
          }
          amin = min(amin, atime);
        }
        if (!ok)
          continue;
        else {
          if (memo2[fkx][fky][tway] > fturn + amin) {
            memo2[fkx][fky][tway] = fturn + amin;
            que.push(bb{fkx, fky, tway, fturn + amin});
          }
        }
      }
      {
        const int nkx = fkx + dx[fway];
        const int nky = fky + dy[fway];
        const int nway = (fway + 2) % 4;
        if (memo2[nkx][nky][nway] > fturn + 1) {
          memo2[nkx][nky][nway] = fturn + 1;
          que.push(bb{nkx, nky, nway, fturn + 1});
        }
      }
    }
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 2070
memory_kb: 3204
final_rank: 14

code_snippet: #include "bits/stdc++.h"
using namespace std;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
const int dx2[4] = {-1, 0, 2, 1};
const int dy2[4] = {0, 2, 1, -1};
struct aa {
  int x;
  int y;
  int turn;
};
int getdis(const vector<vector<int>> &field, const int fx, const int fy,
           const int gx, const int gy) {
  int ans = 999999;
  queue<aa> que;
  vector<vector<int>> memo(field.size(), vector<int>(field[0].size(), 999999));
  que.push(aa{fx, fy, 0});
  while (!que.empty()) {
    aa atop(que.front());
    que.pop();
    if (atop.x == gx && atop.y == gy) {
      ans = atop.turn;
      break;
    }
    for (int i = 0; i < 4; ++i) {
      const int nextx = atop.x + dx[i];
      const int nexty = atop.y + dy[i];
      if (!field[nexty][nextx]) {
        if (atop.turn + 1 < memo[nexty][nextx]) {
          memo[nexty][nextx] = atop.turn + 1;
          que.push(aa{nextx, nexty, atop.turn + 1});
        }
      }
    }
  }
  return ans;
}
struct bb {
  int kx;
  int ky;
  int opway;
  int turn;
};
class Compare {
public:
  bool operator()(const bb &l, const bb &r) { return l.turn > r.turn; }
};
int memo2[52][52][4];
int main() {
  while (1) {
    for (int i = 0; i < 52; ++i) {
      for (int j = 0; j < 52; ++j) {
        for (int k = 0; k < 4; ++k) {
          memo2[i][j][k] = 999999;
        }
      }
    }
    int H, W;
    cin >> H >> W;
    if (!H)
      break;
    vector<vector<int>> field(H + 2, vector<int>(W + 2, true));
    priority_queue<bb, vector<bb>, Compare> que;
    {
      int kx = 99, ky = 99;
      int ox[2];
      int oy[2];
      int num = 0;
      for (int i = 0; i < H; ++i) {
        string st;
        cin >> st;
        for (int j = 0; j < W; ++j) {
          if (st[j] == 'X') {
            kx = min(kx, j + 1);
            ky = min(ky, i + 1);
            field[i + 1][j + 1] = false;
          } else if (st[j] == 'o') {
            field[i + 1][j + 1] = false;
          } else if (st[j] == '.') {
            field[i + 1][j + 1] = false;
            ox[num] = j + 1;
            oy[num] = i + 1;
            num++;
          }
        }
      }
      if (kx == 1 && ky == 1) {
        cout << 0 << endl;
        continue;
      }
      for (int way = 0; way < 4; ++way) {
        int amin = 999999;
        bool ok = true;
        for (int op = 0; op < 2; ++op) {
          int atime = 0;
          for (int lu = 0; lu < 2; ++lu) {
            const int fx = ox[op ^ lu];
            const int fy = oy[op ^ lu];
            int gx = kx + dx2[way];
            int gy = ky + dy2[way];
            if (lu == 1) {
              gx += dx[(way + 1) % 4];
              gy += dy[(way + 1) % 4];
            }
            if (field[gy][gx])
              ok = false;
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[ky + ay][kx + ax] = true;
              }
            }
            atime += getdis(field, fx, fy, gx, gy);
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[ky + ay][kx + ax] = false;
              }
            }
          }
          amin = min(amin, atime);
        }
        if (!ok)
          continue;
        else {
          memo2[kx][ky][way] = amin;
          que.push(bb{kx, ky, way, amin});
        }
      }
    }
    int ans = -1;
    while (!que.empty()) {
      bb atop(que.top());
      que.pop();
      const int fkx = atop.kx;
      const int fky = atop.ky;
      const int fway = atop.opway;
      const int fturn = atop.turn;
      if (fkx == 1 && fky == 1) {
        ans = fturn;
        break;
      }
      for (int tway = 0; tway < 4; ++tway) {
        if (fway == tway)
          continue;
        int amin = 999999;
        bool ok = true;
        for (int op = 0; op < 2; ++op) {
          int atime = 0;
          for (int lu = 0; lu < 2; ++lu) {
            int fx = fkx + dx2[fway];
            int fy = fky + dy2[fway];
            int gx = fkx + dx2[tway];
            int gy = fky + dy2[tway];
            if (lu == 1) {
              gx += dx[(tway + 1) % 4];
              gy += dy[(tway + 1) % 4];
            }
            if (op ^ lu) {
              fx += dx[(fway + 1) % 4];
              fy += dy[(fway + 1) % 4];
            }
            if (field[gy][gx])
              ok = false;
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[fky + ay][fkx + ax] = true;
              }
            }
            atime += getdis(field, fx, fy, gx, gy);
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[fky + ay][fkx + ax] = false;
              }
            }
          }
          amin = min(amin, atime);
        }
        if (!ok)
          continue;
        else {
          if (memo2[fkx][fky][tway] > fturn + amin) {
            memo2[fkx][fky][tway] = fturn + amin;
            que.push(bb{fkx, fky, tway, fturn + amin});
          }
        }
      }
      {
        const int nkx = fkx + dx[fway];
        const int nky = fky + dy[fway];
        const int nway = (fway + 2) % 4;
        if (memo2[nkx][nky][nway] > fturn + 1) {
          memo2[nkx][nky][nway] = fturn + 1;
          que.push(bb{nkx, nky, nway, fturn + 1});
        }
      }
    }
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 1070
memory_kb: 3256
final_rank: 4

code_snippet: #include "bits/stdc++.h"
using namespace std;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
const int dx2[4] = {-1, 0, 2, 1};
const int dy2[4] = {0, 2, 1, -1};
struct aa {
  int x;
  int y;
  int turn;
};
int getdis(const vector<vector<int>> &field, const int fx, const int fy,
           const int gx, const int gy) {
  int ans = 999999;
  queue<aa> que;
  vector<vector<int>> memo(field.size(), vector<int>(field[0].size(), 999999));
  que.push(aa{fx, fy, 0});
  while (!que.empty()) {
    aa atop(que.front());
    que.pop();
    if (atop.x == gx && atop.y == gy) {
      ans = atop.turn;
      break;
    }
    for (int i = 0; i < 4; ++i) {
      const int nextx = atop.x + dx[i];
      const int nexty = atop.y + dy[i];
      if (!field[nexty][nextx]) {
        if (atop.turn + 1 < memo[nexty][nextx]) {
          memo[nexty][nextx] = atop.turn + 1;
          que.push(aa{nextx, nexty, atop.turn + 1});
        }
      }
    }
  }
  return ans;
}
struct bb {
  int kx;
  int ky;
  int opway;
  int turn;
};
class Compare {
public:
  bool operator()(const bb &l, const bb &r) { return l.turn > r.turn; }
};
int memo2[60][60][4];
int main() {
  while (1) {
    for (int i = 0; i < 60; ++i) {
      for (int j = 0; j < 60; ++j) {
        for (int k = 0; k < 4; ++k) {
          memo2[i][j][k] = 999999;
        }
      }
    }
    int H, W;
    cin >> H >> W;
    if (!H)
      break;
    vector<vector<int>> field(H + 2, vector<int>(W + 2, true));
    priority_queue<bb, vector<bb>, Compare> que;
    {
      int kx = 99, ky = 99;
      int ox[2];
      int oy[2];
      int num = 0;
      for (int i = 0; i < H; ++i) {
        string st;
        cin >> st;
        for (int j = 0; j < W; ++j) {
          if (st[j] == 'X') {
            kx = min(kx, j + 1);
            ky = min(ky, i + 1);
            field[i + 1][j + 1] = false;
          } else if (st[j] == 'o') {
            field[i + 1][j + 1] = false;
          } else if (st[j] == '.') {
            field[i + 1][j + 1] = false;
            ox[num] = j + 1;
            oy[num] = i + 1;
            num++;
          }
        }
      }
      if (kx == 1 && ky == 1) {
        cout << 0 << endl;
        continue;
      }
      for (int way = 0; way < 4; ++way) {
        int amin = 999999;
        bool ok = true;
        for (int op = 0; op < 2; ++op) {
          int atime = 0;
          for (int lu = 0; lu < 2; ++lu) {
            const int fx = ox[op ^ lu];
            const int fy = oy[op ^ lu];
            int gx = kx + dx2[way];
            int gy = ky + dy2[way];
            if (lu == 1) {
              gx += dx[(way + 1) % 4];
              gy += dy[(way + 1) % 4];
            }
            if (field[gy][gx])
              ok = false;
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[ky + ay][kx + ax] = true;
              }
            }
            atime += getdis(field, fx, fy, gx, gy);
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[ky + ay][kx + ax] = false;
              }
            }
          }
          amin = min(amin, atime);
        }
        if (!ok)
          continue;
        else {
          memo2[kx][ky][way] = amin;
          que.push(bb{kx, ky, way, amin});
        }
      }
    }
    int ans = -1;
    while (!que.empty()) {
      bb atop(que.top());
      que.pop();
      const int fkx = atop.kx;
      const int fky = atop.ky;
      const int fway = atop.opway;
      const int fturn = atop.turn;
      if (fkx == 1 && fky == 1) {
        ans = fturn;
        break;
      }
      for (int tway = 0; tway < 4; ++tway) {
        if (fway == tway)
          continue;
        int amin = 999999;
        bool ok = true;
        for (int op = 0; op < 2; ++op) {
          int atime = 0;
          for (int lu = 0; lu < 2; ++lu) {
            int fx = fkx + dx2[fway];
            int fy = fky + dy2[fway];
            int gx = fkx + dx2[tway];
            int gy = fky + dy2[tway];
            if (lu == 1) {
              gx += dx[(tway + 1) % 4];
              gy += dy[(tway + 1) % 4];
            }
            if (op ^ lu) {
              fx += dx[(fway + 1) % 4];
              fy += dy[(fway + 1) % 4];
            }
            if (field[gy][gx])
              ok = false;
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[fky + ay][fkx + ax] = true;
              }
            }
            atime += getdis(field, fx, fy, gx, gy);
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[fky + ay][fkx + ax] = false;
              }
            }
          }
          amin = min(amin, atime);
        }
        if (!ok)
          continue;
        else {
          if (memo2[fkx][fky][tway] > fturn + amin) {
            memo2[fkx][fky][tway] = fturn + amin;
            que.push(bb{fkx, fky, tway, fturn + amin});
          }
        }
      }
      {
        const int nkx = fkx + dx[fway];
        const int nky = fky + dy[fway];
        const int nway = (fway + 2) % 4;
        if (memo2[nkx][nky][nway] > fturn + 1) {
          memo2[nkx][nky][nway] = fturn + 1;
          que.push(bb{nkx, nky, nway, fturn + 1});
        }
      }
    }
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 1060
memory_kb: 3200
final_rank: 1

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

const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
const int dx2[4] = {-1, 0, 2, 1};
const int dy2[4] = {0, 2, 1, -1};

struct aa {
  int x, y, turn;
};

int getdis(const vector<vector<int>> &field, const int fx, const int fy, const int gx, const int gy) {
  int ans = 999999;
  queue<aa> que;
  vector<vector<int>> memo(field.size(), vector<int>(field[0].size(), 999999));
  que.push({fx, fy, 0});
  while (!que.empty()) {
    aa atop(que.front());
    que.pop();
    if (atop.x == gx && atop.y == gy) {
      ans = atop.turn;
      break;
    }
    for (int i = 0; i < 4; ++i) {
      const int nextx = atop.x + dx[i];
      const int nexty = atop.y + dy[i];
      if (!field[nexty][nextx]) {
        if (atop.turn + 1 < memo[nexty][nextx]) {
          memo[nexty][nextx] = atop.turn + 1;
          que.push({nextx, nexty, atop.turn + 1});
        }
      }
    }
  }
  return ans;
}

struct bb {
  int kx, ky, opway, turn;
};

class Compare {
public:
  bool operator()(const bb &l, const bb &r) { return l.turn > r.turn; }
};

int memo2[60][60][4];

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);

  while (true) {
    for (int i = 0; i < 60; ++i) {
      for (int j = 0; j < 60; ++j) {
        for (int k = 0; k < 4; ++k) {
          memo2[i][j][k] = 999999;
        }
      }
    }
    int H, W;
    cin >> H >> W;
    if (!H) break;
    vector<vector<int>> field(H + 2, vector<int>(W + 2, true));
    priority_queue<bb, vector<bb>, Compare> que;
    {
      int kx = 99, ky = 99;
      int ox[2];
      int oy[2];
      int num = 0;
      for (int i = 0; i < H; ++i) {
        string st;
        cin >> st;
        for (int j = 0; j < W; ++j) {
          if (st[j] == 'X') {
            kx = min(kx, j + 1);
            ky = min(ky, i + 1);
            field[i + 1][j + 1] = false;
          } else if (st[j] == 'o') {
            field[i + 1][j + 1] = false;
          } else if (st[j] == '.') {
            field[i + 1][j + 1] = false;
            ox[num] = j + 1;
            oy[num] = i + 1;
            num++;
          }
        }
      }
      if (kx == 1 && ky == 1) {
        cout << 0 << '\n';
        continue;
      }
      for (int way = 0; way < 4; ++way) {
        int amin = 999999;
        bool ok = true;
        for (int op = 0; op < 2; ++op) {
          int atime = 0;
          for (int lu = 0; lu < 2; ++lu) {
            const int fx = ox[op ^ lu];
            const int fy = oy[op ^ lu];
            int gx = kx + dx2[way];
            int gy = ky + dy2[way];
            if (lu == 1) {
              gx += dx[(way + 1) % 4];
              gy += dy[(way + 1) % 4];
            }
            if (field[gy][gx]) ok = false;
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[ky + ay][kx + ax] = true;
              }
            }
            atime += getdis(field, fx, fy, gx, gy);
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[ky + ay][kx + ax] = false;
              }
            }
          }
          amin = min(amin, atime);
        }
        if (!ok) continue;
        else {
          memo2[kx][ky][way] = amin;
          que.push({kx, ky, way, amin});
        }
      }
    }
    int ans = -1;
    while (!que.empty()) {
      bb atop(que.top());
      que.pop();
      const int fkx = atop.kx;
      const int fky = atop.ky;
      const int fway = atop.opway;
      const int fturn = atop.turn;
      if (fkx == 1 && fky == 1) {
        ans = fturn;
        break;
      }
      for (int tway = 0; tway < 4; ++tway) {
        if (fway == tway) continue;
        int amin = 999999;
        bool ok = true;
        for (int op = 0; op < 2; ++op) {
          int atime = 0;
          for (int lu = 0; lu < 2; ++lu) {
            int fx = fkx + dx2[fway];
            int fy = fky + dy2[fway];
            int gx = fkx + dx2[tway];
            int gy = fky + dy2[tway];
            if (lu == 1) {
              gx += dx[(tway + 1) % 4];
              gy += dy[(tway + 1) % 4];
            }
            if (op ^ lu) {
              fx += dx[(fway + 1) % 4];
              fy += dy[(fway + 1) % 4];
            }
            if (field[gy][gx]) ok = false;
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[fky + ay][fkx + ax] = true;
              }
            }
            atime += getdis(field, fx, fy, gx, gy);
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[fky + ay][fkx + ax] = false;
              }
            }
          }
          amin = min(amin, atime);
        }
        if (!ok) continue;
        else {
          if (memo2[fkx][fky][tway] > fturn + amin) {
            memo2[fkx][fky][tway] = fturn + amin;
            que.push({fkx, fky, tway, fturn + amin});
          }
        }
      }
      const int nkx = fkx + dx[fway];
      const int nky = fky + dy[fway];
      const int nway = (fway + 2) % 4;
      if (memo2[nkx][nky][nway] > fturn + 1) {
        memo2[nkx][nky][nway] = fturn + 1;
        que.push({nkx, nky, nway, fturn + 1});
      }
    }
    cout << ans << '\n';
  }

  return 0;
}
accuracy: 1
time_ms: 1060
memory_kb: 3416
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
const int dx2[4] = {-1, 0, 2, 1};
const int dy2[4] = {0, 2, 1, -1};
struct aa {
    int x;
    int y;
    int turn;
};
int getdis(const vector<vector<int>> &field, const int fx, const int fy,
           const int gx, const int gy) {
    int ans = 999999;
    queue<aa> que;
    vector<vector<int>> memo(field.size(), vector<int>(field[0].size(), 999999));
    que.push(aa{fx, fy, 0});
    while (!que.empty()) {
        aa atop(que.front());
        que.pop();
        if (atop.x == gx && atop.y == gy) {
            ans = atop.turn;
            break;
        }
        for (int i = 0; i < 4; ++i) {
            const int nextx = atop.x + dx[i];
            const int nexty = atop.y + dy[i];
            if (!field[nexty][nextx]) {
                if (atop.turn + 1 < memo[nexty][nextx]) {
                    memo[nexty][nextx] = atop.turn + 1;
                    que.push(aa{nextx, nexty, atop.turn + 1});
                }
            }
        }
    }
    return ans;
}
struct bb {
    int kx;
    int ky;
    int opway;
    int turn;
};
class Compare {
public:
    bool operator()(const bb &l, const bb &r) { return l.turn > r.turn; }
};
int memo2[60][60][4];
int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    while (1) {
        for (int i = 0; i < 60; ++i) {
            for (int j = 0; j < 60; ++j) {
                for (int k = 0; k < 4; ++k) {
                    memo2[i][j][k] = 999999;
                }
            }
        }
        int H, W;
        cin >> H >> W;
        if (!H)
            break;
        vector<vector<int>> field(H + 2, vector<int>(W + 2, true));
        priority_queue<bb, vector<bb>, Compare> que;
        {
            int kx = 99, ky = 99;
            int ox[2];
            int oy[2];
            int num = 0;
            for (int i = 0; i < H; ++i) {
                string st;
                cin >> st;
                for (int j = 0; j < W; ++j) {
                    if (st[j] == 'X') {
                        kx = min(kx, j + 1);
                        ky = min(ky, i + 1);
                        field[i + 1][j + 1] = false;
                    } else if (st[j] == 'o') {
                        field[i + 1][j + 1] = false;
                    } else if (st[j] == '.') {
                        field[i + 1][j + 1] = false;
                        ox[num] = j + 1;
                        oy[num] = i + 1;
                        num++;
                    }
                }
            }
            if (kx == 1 && ky == 1) {
                cout << 0 << endl;
                continue;
            }
            for (int way = 0; way < 4; ++way) {
                int amin = 999999;
                bool ok = true;
                for (int op = 0; op < 2; ++op) {
                    int atime = 0;
                    for (int lu = 0; lu < 2; ++lu) {
                        const int fx = ox[op ^ lu];
                        const int fy = oy[op ^ lu];
                        int gx = kx + dx2[way];
                        int gy = ky + dy2[way];
                        if (lu == 1) {
                            gx += dx[(way + 1) % 4];
                            gy += dy[(way + 1) % 4];
                        }
                        if (field[gy][gx])
                            ok = false;
                        for (int ax = 0; ax < 2; ++ax) {
                            for (int ay = 0; ay < 2; ++ay) {
                                field[ky + ay][kx + ax] = true;
                            }
                        }
                        atime += getdis(field, fx, fy, gx, gy);
                        for (int ax = 0; ax < 2; ++ax) {
                            for (int ay = 0; ay < 2; ++ay) {
                                field[ky + ay][kx + ax] = false;
                            }
                        }
                    }
                    amin = min(amin, atime);
                }
                if (!ok)
                    continue;
                else {
                    memo2[kx][ky][way] = amin;
                    que.push(bb{kx, ky, way, amin});
                }
            }
        }
        int ans = -1;
        while (!que.empty()) {
            bb atop(que.top());
            que.pop();
            const int fkx = atop.kx;
            const int fky = atop.ky;
            const int fway = atop.opway;
            const int fturn = atop.turn;
            if (fkx == 1 && fky == 1) {
                ans = fturn;
                break;
            }
            for (int tway = 0; tway < 4; ++tway) {
                if (fway == tway)
                    continue;
                int amin = 999999;
                bool ok = true;
                for (int op = 0; op < 2; ++op) {
                    int atime = 0;
                    for (int lu = 0; lu < 2; ++lu) {
                        int fx = fkx + dx2[fway];
                        int fy = fky + dy2[fway];
                        int gx = fkx + dx2[tway];
                        int gy = fky + dy2[tway];
                        if (lu == 1) {
                            gx += dx[(tway + 1) % 4];
                            gy += dy[(tway + 1) % 4];
                        }
                        if (op ^ lu) {
                            fx += dx[(fway + 1) % 4];
                            fy += dy[(fway + 1) % 4];
                        }
                        if (field[gy][gx])
                            ok = false;
                        for (int ax = 0; ax < 2; ++ax) {
                            for (int ay = 0; ay < 2; ++ay) {
                                field[fky + ay][fkx + ax] = true;
                            }
                        }
                        atime += getdis(field, fx, fy, gx, gy);
                        for (int ax = 0; ax < 2; ++ax) {
                            for (int ay = 0; ay < 2; ++ay) {
                                field[fky + ay][fkx + ax] = false;
                            }
                        }
                    }
                    amin = min(amin, atime);
                }
                if (!ok)
                    continue;
                else {
                    if (memo2[fkx][fky][tway] > fturn + amin) {
                        memo2[fkx][fky][tway] = fturn + amin;
                        que.push(bb{fkx, fky, tway, fturn + amin});
                    }
                }
            }
            {
                const int nkx = fkx + dx[fway];
                const int nky = fky + dy[fway];
                const int nway = (fway + 2) % 4;
                if (memo2[nkx][nky][nway] > fturn + 1) {
                    memo2[nkx][nky][nway] = fturn + 1;
                    que.push(bb{nkx, nky, nway, fturn + 1});
                }
            }
        }
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 1070
memory_kb: 3224
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
const int dx2[4] = {-1, 0, 2, 1};
const int dy2[4] = {0, 2, 1, -1};
struct aa {
  int x;
  int y;
  int turn;
};
int getdis(const vector<vector<int>> &field, const int fx, const int fy,
           const int gx, const int gy) {
  int ans = 999999;
  queue<aa> que;
  vector<vector<int>> memo(field.size(), vector<int>(field[0].size(), 999999));
  que.push(aa{fx, fy, 0});
  memo[fy][fx] = 0;
  while (!que.empty()) {
    aa atop(que.front());
    que.pop();
    if (atop.x == gx && atop.y == gy) {
      ans = atop.turn;
      break;
    }
    for (int i = 0; i < 4; ++i) {
      const int nextx = atop.x + dx[i];
      const int nexty = atop.y + dy[i];
      if (!field[nexty][nextx]) {
        if (atop.turn + 1 < memo[nexty][nextx]) {
          memo[nexty][nextx] = atop.turn + 1;
          que.push(aa{nextx, nexty, atop.turn + 1});
        }
      }
    }
  }
  return ans;
}
struct bb {
  int kx;
  int ky;
  int opway;
  int turn;
};
class Compare {
public:
  bool operator()(const bb &l, const bb &r) { return l.turn > r.turn; }
};
int memo2[60][60][4];
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  while (1) {
    for (int i = 0; i < 60; ++i) {
      for (int j = 0; j < 60; ++j) {
        for (int k = 0; k < 4; ++k) {
          memo2[i][j][k] = 999999;
        }
      }
    }
    int H, W;
    cin >> H >> W;
    if (!H)
      break;
    vector<vector<int>> field(H + 2, vector<int>(W + 2, true));
    priority_queue<bb, vector<bb>, Compare> que;
    {
      int kx = 99, ky = 99;
      int ox[2];
      int oy[2];
      int num = 0;
      for (int i = 0; i < H; ++i) {
        string st;
        cin >> st;
        for (int j = 0; j < W; ++j) {
          if (st[j] == 'X') {
            kx = min(kx, j + 1);
            ky = min(ky, i + 1);
            field[i + 1][j + 1] = false;
          } else if (st[j] == 'o') {
            field[i + 1][j + 1] = false;
          } else if (st[j] == '.') {
            field[i + 1][j + 1] = false;
            ox[num] = j + 1;
            oy[num] = i + 1;
            num++;
          }
        }
      }
      if (kx == 1 && ky == 1) {
        cout << 0 << endl;
        continue;
      }
      for (int way = 0; way < 4; ++way) {
        int amin = 999999;
        bool ok = true;
        for (int op = 0; op < 2; ++op) {
          int atime = 0;
          for (int lu = 0; lu < 2; ++lu) {
            const int fx = ox[op ^ lu];
            const int fy = oy[op ^ lu];
            int gx = kx + dx2[way];
            int gy = ky + dy2[way];
            if (lu == 1) {
              gx += dx[(way + 1) % 4];
              gy += dy[(way + 1) % 4];
            }
            if (field[gy][gx])
              ok = false;
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[ky + ay][kx + ax] = true;
              }
            }
            atime += getdis(field, fx, fy, gx, gy);
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[ky + ay][kx + ax] = false;
              }
            }
          }
          amin = min(amin, atime);
        }
        if (!ok)
          continue;
        else {
          memo2[kx][ky][way] = amin;
          que.push(bb{kx, ky, way, amin});
        }
      }
    }
    int ans = -1;
    while (!que.empty()) {
      bb atop(que.top());
      que.pop();
      const int fkx = atop.kx;
      const int fky = atop.ky;
      const int fway = atop.opway;
      const int fturn = atop.turn;
      if (fkx == 1 && fky == 1) {
        ans = fturn;
        break;
      }
      for (int tway = 0; tway < 4; ++tway) {
        if (fway == tway)
          continue;
        int amin = 999999;
        bool ok = true;
        for (int op = 0; op < 2; ++op) {
          int atime = 0;
          for (int lu = 0; lu < 2; ++lu) {
            int fx = fkx + dx2[fway];
            int fy = fky + dy2[fway];
            int gx = fkx + dx2[tway];
            int gy = fky + dy2[tway];
            if (lu == 1) {
              gx += dx[(tway + 1) % 4];
              gy += dy[(tway + 1) % 4];
            }
            if (op ^ lu) {
              fx += dx[(fway + 1) % 4];
              fy += dy[(fway + 1) % 4];
            }
            if (field[gy][gx])
              ok = false;
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[fky + ay][fkx + ax] = true;
              }
            }
            atime += getdis(field, fx, fy, gx, gy);
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[fky + ay][fkx + ax] = false;
              }
            }
          }
          amin = min(amin, atime);
        }
        if (!ok)
          continue;
        else {
          if (memo2[fkx][fky][tway] > fturn + amin) {
            memo2[fkx][fky][tway] = fturn + amin;
            que.push(bb{fkx, fky, tway, fturn + amin});
          }
        }
      }
      {
        const int nkx = fkx + dx[fway];
        const int nky = fky + dy[fway];
        const int nway = (fway + 2) % 4;
        if (memo2[nkx][nky][nway] > fturn + 1) {
          memo2[nkx][nky][nway] = fturn + 1;
          que.push(bb{nkx, nky, nway, fturn + 1});
        }
      }
    }
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 1080
memory_kb: 3536
final_rank: 10

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

const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
const int dx2[4] = {-1, 0, 2, 1};
const int dy2[4] = {0, 2, 1, -1};

struct aa {
    int x, y, turn;
};

int getdis(const vector<vector<int>> &field, const int fx, const int fy, const int gx, const int gy) {
    int ans = 999999;
    queue<aa> que;
    vector<vector<int>> memo(field.size(), vector<int>(field[0].size(), 999999));
    que.push(aa{fx, fy, 0});

    while (!que.empty()) {
        aa atop(que.front());
        que.pop();
        if (atop.x == gx && atop.y == gy) {
            ans = atop.turn;
            break;
        }
        for (int i = 0; i < 4; ++i) {
            const int nextx = atop.x + dx[i];
            const int nexty = atop.y + dy[i];
            if (!field[nexty][nextx]) {
                if (atop.turn + 1 < memo[nexty][nextx]) {
                    memo[nexty][nextx] = atop.turn + 1;
                    que.push(aa{nextx, nexty, atop.turn + 1});
                }
            }
        }
    }

    return ans;
}

struct bb {
    int kx, ky, opway, turn;
};

class Compare {
public:
    bool operator()(const bb &l, const bb &r) { return l.turn > r.turn; }
};

int memo2[60][60][4];

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    while (true) {
        for (int i = 0; i < 60; ++i) {
            for (int j = 0; j < 60; ++j) {
                for (int k = 0; k < 4; ++k) {
                    memo2[i][j][k] = 999999;
                }
            }
        }

        int H, W;
        cin >> H >> W;
        if (!H) break;

        vector<vector<int>> field(H + 2, vector<int>(W + 2, true));
        priority_queue<bb, vector<bb>, Compare> que;

        int kx = 99, ky = 99;
        int ox[2];
        int oy[2];
        int num = 0;

        for (int i = 0; i < H; ++i) {
            string st;
            cin >> st;
            for (int j = 0; j < W; ++j) {
                if (st[j] == 'X') {
                    kx = min(kx, j + 1);
                    ky = min(ky, i + 1);
                    field[i + 1][j + 1] = false;
                } else if (st[j] == 'o') {
                    field[i + 1][j + 1] = false;
                } else if (st[j] == '.') {
                    field[i + 1][j + 1] = false;
                    ox[num] = j + 1;
                    oy[num] = i + 1;
                    num++;
                }
            }
        }

        if (kx == 1 && ky == 1) {
            cout << 0 << endl;
            continue;
        }

        for (int way = 0; way < 4; ++way) {
            int amin = 999999;
            bool ok = true;
            for (int op = 0; op < 2; ++op) {
                int atime = 0;
                for (int lu = 0; lu < 2; ++lu) {
                    const int fx = ox[op ^ lu];
                    const int fy = oy[op ^ lu];
                    int gx = kx + dx2[way];
                    int gy = ky + dy2[way];
                    if (lu == 1) {
                        gx += dx[(way + 1) % 4];
                        gy += dy[(way + 1) % 4];
                    }
                    if (field[gy][gx]) ok = false;
                    for (int ax = 0; ax < 2; ++ax) {
                        for (int ay = 0; ay < 2; ++ay) {
                            field[ky + ay][kx + ax] = true;
                        }
                    }
                    atime += getdis(field, fx, fy, gx, gy);
                    for (int ax = 0; ax < 2; ++ax) {
                        for (int ay = 0; ay < 2; ++ay) {
                            field[ky + ay][kx + ax] = false;
                        }
                    }
                }
                amin = min(amin, atime);
            }
            if (!ok) continue;
            else {
                memo2[kx][ky][way] = amin;
                que.push(bb{kx, ky, way, amin});
            }
        }

        int ans = -1;

        while (!que.empty()) {
            bb atop(que.top());
            que.pop();
            const int fkx = atop.kx;
            const int fky = atop.ky;
            const int fway = atop.opway;
            const int fturn = atop.turn;
            if (fkx == 1 && fky == 1) {
                ans = fturn;
                break;
            }
            for (int tway = 0; tway < 4; ++tway) {
                if (fway == tway) continue;
                int amin = 999999;
                bool ok = true;
                for (int op = 0; op < 2; ++op) {
                    int atime = 0;
                    for (int lu = 0; lu < 2; ++lu) {
                        int fx = fkx + dx2[fway];
                        int fy = fky + dy2[fway];
                        int gx = fkx + dx2[tway];
                        int gy = fky + dy2[tway];
                        if (lu == 1) {
                            gx += dx[(tway + 1) % 4];
                            gy += dy[(tway + 1) % 4];
                        }
                        if (op ^ lu) {
                            fx += dx[(fway + 1) % 4];
                            fy += dy[(fway + 1) % 4];
                        }
                        if (field[gy][gx]) ok = false;
                        for (int ax = 0; ax < 2; ++ax) {
                            for (int ay = 0; ay < 2; ++ay) {
                                field[fky + ay][fkx + ax] = true;
                            }
                        }
                        atime += getdis(field, fx, fy, gx, gy);
                        for (int ax = 0; ax < 2; ++ax) {
                            for (int ay = 0; ay < 2; ++ay) {
                                field[fky + ay][fkx + ax] = false;
                            }
                        }
                    }
                    amin = min(amin, atime);
                }
                if (!ok) continue;
                else {
                    if (memo2[fkx][fky][tway] > fturn + amin) {
                        memo2[fkx][fky][tway] = fturn + amin;
                        que.push(bb{fkx, fky, tway, fturn + amin});
                    }
                }
            }
            {
                const int nkx = fkx + dx[fway];
                const int nky = fky + dy[fway];
                const int nway = (fway + 2) % 4;
                if (memo2[nkx][nky][nway] > fturn + 1) {
                    memo2[nkx][nky][nway] = fturn + 1;
                    que.push(bb{nkx, nky, nway, fturn + 1});
                }
            }
        }

        cout << ans << endl;
    }

    return 0;
}
accuracy: 1
time_ms: 1070
memory_kb: 3448
final_rank: 7

code_snippet: #include <iostream>
#include <vector>
#include <queue>
using namespace std;

const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
const int dx2[4] = {-1, 0, 2, 1};
const int dy2[4] = {0, 2, 1, -1};

struct aa {
    int x;
    int y;
    int turn;
};

int getdis(const vector<vector<int>> &field, const int fx, const int fy,
           const int gx, const int gy) {
  int ans = 999999;
  queue<aa> que;
  vector<vector<int>> memo(field.size(), vector<int>(field[0].size(), 999999));
  que.push(aa{fx, fy, 0});
  while (!que.empty()) {
    aa atop(que.front());
    que.pop();
    if (atop.x == gx && atop.y == gy) {
      ans = atop.turn;
      break;
    }
    for (int i = 0; i < 4; ++i) {
      const int nextx = atop.x + dx[i];
      const int nexty = atop.y + dy[i];
      if (!field[nexty][nextx]) {
        if (atop.turn + 1 < memo[nexty][nextx]) {
          memo[nexty][nextx] = atop.turn + 1;
          que.push(aa{nextx, nexty, atop.turn + 1});
        }
      }
    }
  }
  return ans;
}

struct bb {
  int kx;
  int ky;
  int opway;
  int turn;
};

class Compare {
public:
  bool operator()(const bb &l, const bb &r) { return l.turn > r.turn; }
};

int memo2[60][60][4];

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  while (true) {
    for (int i = 0; i < 60; ++i) {
      for (int j = 0; j < 60; ++j) {
        for (int k = 0; k < 4; ++k) {
          memo2[i][j][k] = 999999;
        }
      }
    }
    int H, W;
    cin >> H >> W;
    if (!H) break;
    vector<vector<int>> field(H + 2, vector<int>(W + 2, true));
    priority_queue<bb, vector<bb>, Compare> que;
    {
      int kx = 99, ky = 99;
      int ox[2];
      int oy[2];
      int num = 0;
      for (int i = 0; i < H; ++i) {
        string st;
        cin >> st;
        for (int j = 0; j < W; ++j) {
          if (st[j] == 'X') {
            kx = min(kx, j + 1);
            ky = min(ky, i + 1);
            field[i + 1][j + 1] = false;
          } else if (st[j] == 'o') {
            field[i + 1][j + 1] = false;
          } else if (st[j] == '.') {
            field[i + 1][j + 1] = false;
            ox[num] = j + 1;
            oy[num] = i + 1;
            num++;
          }
        }
      }
      if (kx == 1 && ky == 1) {
        cout << 0 << endl;
        continue;
      }
      for (int way = 0; way < 4; ++way) {
        int amin = 999999;
        bool ok = true;
        for (int op = 0; op < 2; ++op) {
          int atime = 0;
          for (int lu = 0; lu < 2; ++lu) {
            const int fx = ox[op ^ lu];
            const int fy = oy[op ^ lu];
            int gx = kx + dx2[way];
            int gy = ky + dy2[way];
            if (lu == 1) {
              gx += dx[(way + 1) % 4];
              gy += dy[(way + 1) % 4];
            }
            if (field[gy][gx])
              ok = false;
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[ky + ay][kx + ax] = true;
              }
            }
            atime += getdis(field, fx, fy, gx, gy);
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[ky + ay][kx + ax] = false;
              }
            }
          }
          amin = min(amin, atime);
        }
        if (!ok)
          continue;
        else {
          memo2[kx][ky][way] = amin;
          que.push(bb{kx, ky, way, amin});
        }
      }
    }
    int ans = -1;
    while (!que.empty()) {
      bb atop(que.top());
      que.pop();
      const int fkx = atop.kx;
      const int fky = atop.ky;
      const int fway = atop.opway;
      const int fturn = atop.turn;
      if (fkx == 1 && fky == 1) {
        ans = fturn;
        break;
      }
      for (int tway = 0; tway < 4; ++tway) {
        if (fway == tway)
          continue;
        int amin = 999999;
        bool ok = true;
        for (int op = 0; op < 2; ++op) {
          int atime = 0;
          for (int lu = 0; lu < 2; ++lu) {
            int fx = fkx + dx2[fway];
            int fy = fky + dy2[fway];
            int gx = fkx + dx2[tway];
            int gy = fky + dy2[tway];
            if (lu == 1) {
              gx += dx[(tway + 1) % 4];
              gy += dy[(tway + 1) % 4];
            }
            if (op ^ lu) {
              fx += dx[(fway + 1) % 4];
              fy += dy[(fway + 1) % 4];
            }
            if (field[gy][gx])
              ok = false;
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[fky + ay][fkx + ax] = true;
              }
            }
            atime += getdis(field, fx, fy, gx, gy);
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[fky + ay][fkx + ax] = false;
              }
            }
          }
          amin = min(amin, atime);
        }
        if (!ok)
          continue;
        else {
          if (memo2[fkx][fky][tway] > fturn + amin) {
            memo2[fkx][fky][tway] = fturn + amin;
            que.push(bb{fkx, fky, tway, fturn + amin});
          }
        }
      }
      {
        const int nkx = fkx + dx[fway];
        const int nky = fky + dy[fway];
        const int nway = (fway + 2) % 4;
        if (memo2[nkx][nky][nway] > fturn + 1) {
          memo2[nkx][nky][nway] = fturn + 1;
          que.push(bb{nkx, nky, nway, fturn + 1});
        }
      }
    }
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 1070
memory_kb: 3216
final_rank: 2

code_snippet: #include "bits/stdc++.h"
using namespace std;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
const int dx2[4] = {-1, 0, 2, 1};
const int dy2[4] = {0, 2, 1, -1};
struct aa {
  int x;
  int y;
  int turn;
};
int getdis(const vector<vector<int>> &field, const int fx, const int fy,
           const int gx, const int gy) {
  int ans = 999999;
  queue<aa> que;
  vector<vector<int>> memo(field.size(), vector<int>(field[0].size(), 999999));
  que.push(aa{fx, fy, 0});
  while (!que.empty()) {
    aa atop(que.front());
    que.pop();
    if (atop.x == gx && atop.y == gy) {
      ans = atop.turn;
      break;
    }
    for (int i = 0; i < 4; ++i) {
      const int nextx = atop.x + dx[i];
      const int nexty = atop.y + dy[i];
      if (!field[nexty][nextx]) {
        if (atop.turn + 1 < memo[nexty][nextx]) {
          memo[nexty][nextx] = atop.turn + 1;
          que.push(aa{nextx, nexty, atop.turn + 1});
        }
      }
    }
  }
  return ans;
}
struct bb {
  int kx;
  int ky;
  int opway;
  int turn;
};
class Compare {
public:
  bool operator()(const bb &l, const bb &r) { return l.turn > r.turn; }
};
int memo2[60][60][4];
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  while (1) {
    for (int i = 0; i < 60; ++i) {
      for (int j = 0; j < 60; ++j) {
        for (int k = 0; k < 4; ++k) {
          memo2[i][j][k] = 999999;
        }
      }
    }
    int H, W;
    cin >> H >> W;
    if (!H)
      break;
    vector<vector<int>> field(H + 2, vector<int>(W + 2, true));
    priority_queue<bb, vector<bb>, Compare> que;
    {
      int kx = 99, ky = 99;
      int ox[2];
      int oy[2];
      int num = 0;
      for (int i = 0; i < H; ++i) {
        string st;
        cin >> st;
        for (int j = 0; j < W; ++j) {
          if (st[j] == 'X') {
            kx = min(kx, j + 1);
            ky = min(ky, i + 1);
            field[i + 1][j + 1] = false;
          } else if (st[j] == 'o') {
            field[i + 1][j + 1] = false;
          } else if (st[j] == '.') {
            field[i + 1][j + 1] = false;
            ox[num] = j + 1;
            oy[num] = i + 1;
            num++;
          }
        }
      }
      if (kx == 1 && ky == 1) {
        cout << 0 << endl;
        continue;
      }
      for (int way = 0; way < 4; ++way) {
        int amin = 999999;
        bool ok = true;
        for (int op = 0; op < 2; ++op) {
          int atime = 0;
          for (int lu = 0; lu < 2; ++lu) {
            const int fx = ox[op ^ lu];
            const int fy = oy[op ^ lu];
            int gx = kx + dx2[way];
            int gy = ky + dy2[way];
            if (lu == 1) {
              gx += dx[(way + 1) % 4];
              gy += dy[(way + 1) % 4];
            }
            if (field[gy][gx])
              ok = false;
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[ky + ay][kx + ax] = true;
              }
            }
            atime += getdis(field, fx, fy, gx, gy);
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[ky + ay][kx + ax] = false;
              }
            }
          }
          amin = min(amin, atime);
        }
        if (!ok)
          continue;
        else {
          memo2[kx][ky][way] = amin;
          que.push(bb{kx, ky, way, amin});
        }
      }
    }
    int ans = -1;
    while (!que.empty()) {
      bb atop(que.top());
      que.pop();
      const int fkx = atop.kx;
      const int fky = atop.ky;
      const int fway = atop.opway;
      const int fturn = atop.turn;
      if (fkx == 1 && fky == 1) {
        ans = fturn;
        break;
      }
      for (int tway = 0; tway < 4; ++tway) {
        if (fway == tway)
          continue;
        int amin = 999999;
        bool ok = true;
        for (int op = 0; op < 2; ++op) {
          int atime = 0;
          for (int lu = 0; lu < 2; ++lu) {
            int fx = fkx + dx2[fway];
            int fy = fky + dy2[fway];
            int gx = fkx + dx2[tway];
            int gy = fky + dy2[tway];
            if (lu == 1) {
              gx += dx[(tway + 1) % 4];
              gy += dy[(tway + 1) % 4];
            }
            if (op ^ lu) {
              fx += dx[(fway + 1) % 4];
              fy += dy[(fway + 1) % 4];
            }
            if (field[gy][gx])
              ok = false;
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[fky + ay][fkx + ax] = true;
              }
            }
            atime += getdis(field, fx, fy, gx, gy);
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[fky + ay][fkx + ax] = false;
              }
            }
          }
          amin = min(amin, atime);
        }
        if (!ok)
          continue;
        else {
          if (memo2[fkx][fky][tway] > fturn + amin) {
            memo2[fkx][fky][tway] = fturn + amin;
            que.push(bb{fkx, fky, tway, fturn + amin});
          }
        }
      }
      {
        const int nkx = fkx + dx[fway];
        const int nky = fky + dy[fway];
        const int nway = (fway + 2) % 4;
        if (memo2[nkx][nky][nway] > fturn + 1) {
          memo2[nkx][nky][nway] = fturn + 1;
          que.push(bb{nkx, nky, nway, fturn + 1});
        }
      }
    }
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 1090
memory_kb: 3540
final_rank: 11

code_snippet: #include "bits/stdc++.h"
using namespace std;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
const int dx2[4] = {-1, 0, 2, 1};
const int dy2[4] = {0, 2, 1, -1};
struct aa {
  int x;
  int y;
  int turn;
};
int getdis(const vector<vector<int>> &field, const int fx, const int fy,
           const int gx, const int gy) {
  int ans = 999999;
  queue<aa> que;
  vector<vector<int>> memo(field.size(), vector<int>(field[0].size(), 999999));
  que.push(aa{fx, fy, 0});
  while (!que.empty()) {
    aa atop(que.front());
    que.pop();
    if (atop.x == gx && atop.y == gy) {
      ans = atop.turn;
      break;
    }
    for (int i = 0; i < 4; ++i) {
      const int nextx = atop.x + dx[i];
      const int nexty = atop.y + dy[i];
      if (!field[nexty][nextx]) {
        if (atop.turn + 1 < memo[nexty][nextx]) {
          memo[nexty][nextx] = atop.turn + 1;
          que.push(aa{nextx, nexty, atop.turn + 1});
        }
      }
    }
  }
  return ans;
}
struct bb {
  int kx;
  int ky;
  int opway;
  int turn;
};
class Compare {
public:
  bool operator()(const bb &l, const bb &r) { return l.turn > r.turn; }
};
int memo2[60][60][4];
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  while (1) {
    for (int i = 0; i < 60; ++i) {
      for (int j = 0; j < 60; ++j) {
        for (int k = 0; k < 4; ++k) {
          memo2[i][j][k] = 999999;
        }
      }
    }
    int H, W;
    cin >> H >> W;
    if (!H)
      break;
    vector<vector<int>> field(H + 2, vector<int>(W + 2, true));
    priority_queue<bb, vector<bb>, Compare> que;
    {
      int kx = 99, ky = 99;
      int ox[2];
      int oy[2];
      int num = 0;
      for (int i = 0; i < H; ++i) {
        string st;
        cin >> st;
        for (int j = 0; j < W; ++j) {
          if (st[j] == 'X') {
            kx = min(kx, j + 1);
            ky = min(ky, i + 1);
            field[i + 1][j + 1] = false;
          } else if (st[j] == 'o') {
            field[i + 1][j + 1] = false;
          } else if (st[j] == '.') {
            field[i + 1][j + 1] = false;
            ox[num] = j + 1;
            oy[num] = i + 1;
            num++;
          }
        }
      }
      if (kx == 1 && ky == 1) {
        cout << 0 << endl;
        continue;
      }
      for (int way = 0; way < 4; ++way) {
        int amin = 999999;
        bool ok = true;
        for (int op = 0; op < 2; ++op) {
          int atime = 0;
          for (int lu = 0; lu < 2; ++lu) {
            const int fx = ox[op ^ lu];
            const int fy = oy[op ^ lu];
            int gx = kx + dx2[way];
            int gy = ky + dy2[way];
            if (lu == 1) {
              gx += dx[(way + 1) % 4];
              gy += dy[(way + 1) % 4];
            }
            if (field[gy][gx])
              ok = false;
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[ky + ay][kx + ax] = true;
              }
            }
            atime += getdis(field, fx, fy, gx, gy);
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[ky + ay][kx + ax] = false;
              }
            }
          }
          amin = min(amin, atime);
        }
        if (!ok)
          continue;
        else {
          memo2[kx][ky][way] = amin;
          que.push(bb{kx, ky, way, amin});
        }
      }
    }
    int ans = -1;
    while (!que.empty()) {
      bb atop(que.top());
      que.pop();
      const int fkx = atop.kx;
      const int fky = atop.ky;
      const int fway = atop.opway;
      const int fturn = atop.turn;
      if (fkx == 1 && fky == 1) {
        ans = fturn;
        break;
      }
      for (int tway = 0; tway < 4; ++tway) {
        if (fway == tway)
          continue;
        int amin = 999999;
        bool ok = true;
        for (int op = 0; op < 2; ++op) {
          int atime = 0;
          for (int lu = 0; lu < 2; ++lu) {
            int fx = fkx + dx2[fway];
            int fy = fky + dy2[fway];
            int gx = fkx + dx2[tway];
            int gy = fky + dy2[tway];
            if (lu == 1) {
              gx += dx[(tway + 1) % 4];
              gy += dy[(tway + 1) % 4];
            }
            if (op ^ lu) {
              fx += dx[(fway + 1) % 4];
              fy += dy[(fway + 1) % 4];
            }
            if (field[gy][gx])
              ok = false;
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[fky + ay][fkx + ax] = true;
              }
            }
            atime += getdis(field, fx, fy, gx, gy);
            for (int ax = 0; ax < 2; ++ax) {
              for (int ay = 0; ay < 2; ++ay) {
                field[fky + ay][fkx + ax] = false;
              }
            }
          }
          amin = min(amin, atime);
        }
        if (!ok)
          continue;
        else {
          if (memo2[fkx][fky][tway] > fturn + amin) {
            memo2[fkx][fky][tway] = fturn + amin;
            que.push(bb{fkx, fky, tway, fturn + amin});
          }
        }
      }
      {
        const int nkx = fkx + dx[fway];
        const int nky = fky + dy[fway];
        const int nway = (fway + 2) % 4;
        if (memo2[nkx][nky][nway] > fturn + 1) {
          memo2[nkx][nky][nway] = fturn + 1;
          que.push(bb{nkx, nky, nway, fturn + 1});
        }
      }
    }
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 1100
memory_kb: 3536
final_rank: 12