#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
#include <cassert>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
#include <iomanip>
#include <fstream>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
#define chmax(a,b) (a<b?(a=b,1):0)
#define chmin(a,b) (a>b?(a=b,1):0)
#define valid(y,x,h,w) (0<=y&&y<h&&0<=x&&x<w)
const int INF = 1<<29;
typedef long long ll;
typedef pair<int,int> pii;

char ba[50][50];

struct P {
  int y, x;
  int d;
  int dist;
  P(int y, int x, int d, int dist) :
    y(y),x(x),d(d),dist(dist) {}
  bool operator<(const P &p) const {
    return dist > p.dist;
  }
};

int dist[50][50][4];

int &get(const P &p) {
  return dist[p.y][p.x][p.d];
}

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

const int kdy[4] = {0,0,1,1};
const int kdx[4] = {0,1,0,1};

const int pdy[4][2] = {0,1,2,2,0,1,-1,-1};
const int pdx[4][2] = {2,2,0,1,-1,-1,0,1};

int h,w;

bool ok(int y, int x) {
  return valid(y,x,h,w) && ba[y][x]!='*';
}

bool isKing(int i, int j, int y, int x) {
  REP(k,4) {
    int yy=y+kdy[k];
    int xx=x+kdx[k];
    if (yy==i&xx==j) return 1;
  }
  return 0;
}

int dist2[2][50][50];

void calcPawnDist(int id, int i, int j, int ky, int kx) {
  queue<pii> Q;
  Q.push(pii(i,j));
  dist2[id][i][j] = 0;
  while(!Q.empty()) {
    pii p = Q.front(); Q.pop();
    REP(k,4) {
      int y=p.first+dy[k];
      int x=p.second+dx[k];
      if (!ok(y,x) || isKing(y,x,ky,kx) || dist2[id][y][x]!=-1) continue;
      Q.push(pii(y,x));
      dist2[id][y][x] = dist2[id][p.first][p.second]+1;
    }
  }
}

int main() {
  while(cin>>h>>w,h||w) {
    REP(i,h)REP(j,w)cin>>ba[i][j];
    int ky=-1, kx;
    vector<pii> ps;
    REP(i,h)REP(j,w) {
      if (ky==-1 && ba[i][j]=='X') ky = i, kx = j;
      if (ba[i][j] == '.') ps.push_back(pii(i,j));
    }
    assert(ps.size() == 2 && ky != -1);

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

    memset(dist2,-1,sizeof(dist2));
    REP(i,2) {
      int y = ps[i].first;
      int x = ps[i].second;
      calcPawnDist(i,y,x,ky,kx);
    }
    
    memset(dist, 0x3f, sizeof(dist));
    priority_queue<P> PQ;

    REP(d,4) {
      int cost[2][2];
      bool f = 1;
      REP(i,2) {
        int y=ky+pdy[d][i];
        int x=kx+pdx[d][i];
        if (!ok(y,x)) { f = 0;break; }
        REP(j,2) {
          cost[i][j] = dist2[j][y][x];
          if (cost[i][j] == -1) f = 0;
        }
      }
      if (f) {
        int dis = min(cost[0][0]+cost[1][1], cost[0][1]+cost[1][0]);
        dist[ky][kx][d] = dis;
        PQ.push(P(ky,kx,d,dis));
      }
    }
    
    int ans = -1;
    
    while(!PQ.empty()) {
      P p = PQ.top(); PQ.pop();

      if (p.dist > get(p)) continue;

      // cout << p.dist << endl;
      // char c[h][w];
      // REP(i,h)REP(j,w)c[i][j]=(ba[i][j]=='*'?'*':'o');
      // REP(k,4) {
      //   int y=p.y + kdy[k];
      //   int x=p.x + kdx[k];
      //   c[y][x]='X';
      // }
      // REP(i,2) c[p.y+pdy[p.d][i]][p.x+pdx[p.d][i]] = '.';
      // REP(i,h) { REP(j,w) cout << c[i][j]; cout << endl;}
      // cout << endl;

      if (p.y==0 && p.x==0) {
        ans = p.dist;
        break;
      }

      // pawn
      memset(dist2,-1,sizeof(dist2));
      REP(i,2) {
        int y = p.y+pdy[p.d][i];
        int x = p.x+pdx[p.d][i];
        calcPawnDist(i,y,x,p.y,p.x);
      }

      REP(d,4) {
        int cost[2][2];
        bool f = 1;
        REP(i,2) {
          int ty = p.y+pdy[d][i];
          int tx = p.x+pdx[d][i];
          if (!ok(ty,tx)) {f = 0;break;}
          REP(j,2) {
            cost[i][j] = dist2[j][ty][tx];
            if (cost[i][j] == -1) f = 0;
          }
        }
        if (f) {
          int dis = min(cost[0][0]+cost[1][1], cost[0][1]+cost[1][0]);
          P nxt(p.y,p.x,d,p.dist+dis);
          if (get(nxt) > p.dist + dis) {
            get(nxt) = p.dist + dis;
            PQ.push(nxt);
          }
        }
      }
      
      // king
      int y = p.y+dy[p.d];
      int x = p.x+dx[p.d];
      P nxt(y,x,(p.d+2)%4,p.dist+1);
      if (get(nxt) > p.dist+1) {
        get(nxt) = p.dist + 1;
        PQ.push(nxt);
      }
    }
    cout << ans << endl;
  }
}

Measured memory_bytes: 1292