#include <tr1/unordered_set>
#include <iostream>
#include <cstdio>
#include <vector>
#include <list>
#include <cmath>
#include <fstream>
#include <algorithm>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <complex>
#include <iterator>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <stack>
#include <climits>
#include <deque>
#include <bitset>
#include <cassert>
#include <ctime>
using namespace std;
using namespace tr1;
typedef long long ll;
typedef pair<int,int> pii;
const int dy[]={-1,0,1,0},dx[]={0,1,0,-1};
// adjust problem by problem
const double EPS=1e-8;
const double PI=acos(-1.0);
#ifdef __GNUC__
int popcount(int n){return __builtin_popcount(n);}
int popcount(ll n){return __builtin_popcountll(n);}
#endif
#ifndef __GNUC__
template<class T> int popcount(T n){int cnt=0;while(n){if(n%2)cnt++;n/=2;}return cnt;}
#endif
template<class T>int SIZE(T a){return a.size();}
template<class T>string IntToString(T num){string res;stringstream ss;ss<<num;return ss.str();}
template<class T>T StringToInt(string str){T res=0;for(int i=0;i<SIZE(str);i++)res=(res*10+str[i]-'0');return res;}
template<class T>T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template<class T>T lcm(T a,T b){return a/gcd(a,b)*b;}
bool EQ(double a,double b){return abs(a-b)<EPS;}
void fastStream(){cin.tie(0);std::ios_base::sync_with_stdio(0);}
vector<string> split(string str,char del){
  vector<string> res;
  for(int i=0,s=0;i<SIZE(str);i++){
    if(str[i]==del){if(i-s!=0)res.push_back(str.substr(s,i-s));s=i+1;}
    else if(i==SIZE(str)-1){res.push_back(str.substr(s));}
  }
  return res;
}

typedef vector<pii> vec;
typedef vector<vec> mat;

int sy,sx;
int gy,gx;
int goal[3][3];
// 0->red,1->blue,2->white
mat field(3,vec(3));
int fieldMask;
const int INF=1<<30;
unordered_set<int> used;
int ary[3][3];

int dcdColor(int a,int b){
  if(a==0&&b==1)return 2;
  else if(a==0&&b==2)return 1;
  else if(a==1&&b==0)return 2;
  else if(a==1&&b==2)return 0;
  else if(a==2&&b==0)return 1;
  else if(a==2&&b==1)return 0;
}

int toVal(int a,int b){
  if(a==0&&b==1)return 0;
  if(a==0&&b==2)return 1;
  if(a==1&&b==0)return 2;
  if(a==1&&b==2)return 3;
  if(a==2&&b==0)return 4;
  if(a==2&&b==1)return 5;
  return 6;
}

// maskにvalをset
int setMask(int mask,int pos,int val){
  for(int i=0;i<3;i++){
    if((val>>i)&1)mask|=(1<<(3*pos+i));
    else mask&=~(1<<(3*pos+i));
  }
  return mask;
}
// maskのposにある値をget
int getVal(int mask,int pos){
  int res=0;
  for(int i=0;i<3;i++)
    if((mask>>(3*pos+i))&1)res|=(1<<i);
  return res;
}

// // iddfsでgoalに到達できるかどうかを探索
// // 辿りつけなければ-1を返す
int iddfs(int depth,int limDepth,int cy,int cx,int cnt){
  // 距離を計算
  if(depth==limDepth){
    if(cnt==0)return depth;
    return -1;
  }
  // 異なる面の数がのこりの移動回数+1以下ならok
  if(cnt>(limDepth-depth)+1)return -1;
  if(abs(cy-gy)+abs(cx-gx)>(limDepth-depth))return -1;
  for(int i=0;i<4;i++){
    int ncnt=cnt;
    int ny=cy+dy[i],nx=cx+dx[i];
    // enable to move
    if(ny>=0&&nx>=0&&ny<3&&nx<3){
      ncnt-=(field[ny][nx].first!=goal[ny][nx]);
      ncnt-=(field[cy][cx].first!=goal[cy][cx]);
      pii p1=field[cy][cx];
      pii p2=field[ny][nx];
      int bMask=fieldMask;
      // 移動先の要素を回転させて今の場所へ持ってくる
      if(nx!=cx){
        field[cy][cx].first=ary[field[ny][nx].first][field[ny][nx].second];
        field[cy][cx].second=field[ny][nx].second;
        fieldMask=setMask(fieldMask,cy*3+cx,toVal(field[cy][cx].first,field[cy][cx].second));
      }
      else if(ny!=cy){
        field[cy][cx]=field[ny][nx];
        swap(field[cy][cx].first,field[cy][cx].second);
        fieldMask=setMask(fieldMask,cy*3+cx,toVal(field[cy][cx].first,field[cy][cx].second));
      }
      field[ny][nx].first=field[ny][nx].second=-1;
      fieldMask=setMask(fieldMask,ny*3+nx,toVal(field[ny][nx].first,field[ny][nx].second));
      if(used.count(fieldMask)==0){
        ncnt+=(field[ny][nx].first!=goal[ny][nx]);
        ncnt+=(field[cy][cx].first!=goal[cy][cx]);
        used.insert(fieldMask);
        int res=iddfs(depth+1,limDepth,ny,nx,ncnt);
        if(res!=-1)return res;
        used.erase(fieldMask);
      }
      // back track
      fieldMask=bMask;
      field[cy][cx]=p1;
      field[ny][nx]=p2;
    }
  }
  return -1;
}

int ans;
// dfsでgoalに到達できるかどうかを探索
// 辿りつけなければ-1を返す
void dfs(int depth,int cy,int cx,int cnt){
  // 距離を計算
  if(cnt==0){
    ans=min(ans,depth);
    return;
  }
  if(cnt>(ans-depth)+1)return;
  if(abs(cy-gy)+abs(cx-gx)>(ans-depth))return;
  for(int i=0;i<4;i++){
    int ncnt=cnt;
    int ny=cy+dy[i],nx=cx+dx[i];
    // enable to move
    if(ny>=0&&nx>=0&&ny<3&&nx<3){
      ncnt-=(field[ny][nx].first!=goal[ny][nx]);
      ncnt-=(field[cy][cx].first!=goal[cy][cx]);
      pii p1=field[cy][cx];
      pii p2=field[ny][nx];
      int bMask=fieldMask;
      // 移動先の要素を回転させて今の場所へ持ってくる
      if(nx!=cx){
        field[cy][cx].first=ary[field[ny][nx].first][field[ny][nx].second];
        field[cy][cx].second=field[ny][nx].second;
        fieldMask=setMask(fieldMask,cy*3+cx,toVal(field[cy][cx].first,field[cy][cx].second));
      }
      else if(ny!=cy){
        field[cy][cx]=field[ny][nx];
        swap(field[cy][cx].first,field[cy][cx].second);
        fieldMask=setMask(fieldMask,cy*3+cx,toVal(field[cy][cx].first,field[cy][cx].second));
      }
      field[ny][nx].first=field[ny][nx].second=-1;
      fieldMask=setMask(fieldMask,ny*3+nx,toVal(field[ny][nx].first,field[ny][nx].second));
      if(used.count(fieldMask)==0){
        ncnt+=(field[ny][nx].first!=goal[ny][nx]);
        ncnt+=(field[cy][cx].first!=goal[cy][cx]);
        used.insert(fieldMask);
        dfs(depth+1,ny,nx,ncnt);
        used.erase(fieldMask);
      }
      fieldMask=bMask;
      // back track
      field[cy][cx]=p1;
      field[ny][nx]=p2;
    }
  }
}


int main(){
  for(int i=0;i<3;i++)
    for(int j=0;j<3;j++)
      ary[i][j]=dcdColor(i,j);
  while(cin>>sx>>sy&&(sx|sy)){
    // topfaceがgoalとmatchしたら終了
    for(int i=0;i<3;i++){
      for(int j=0;j<3;j++){
        char ch;
        cin>>ch;
        if(ch=='R')goal[i][j]=0;
        else if(ch=='B')goal[i][j]=1;
        else if(ch=='W')goal[i][j]=2;
        else{
          goal[i][j]=-1;
          gy=i,gx=j;
        }
      }
    }
    sy--,sx--;
    // start地点をセット
    for(int i=0;i<3;i++){
      for(int j=0;j<3;j++){
        if(i==sy&&j==sx){
          field[i][j]=pii(-1,-1);
          fieldMask=setMask(fieldMask,i*3+j,6);
        }
        else{
          field[i][j]=pii(2,0);
          fieldMask=setMask(fieldMask,i*3+j,toVal(2,0));
        }
      }
    }
    ans=31;
    int cnt=0;
    for(int i=0;i<3;i++)
      for(int j=0;j<3;j++)
        cnt+=(field[i][j].first!=goal[i][j]);
    used.insert(fieldMask);
    dfs(0,sy,sx,cnt);
    if(ans==31)cout<<-1<<endl;
    else cout<<ans<<endl;
    // iddfs
    // int res=-1;
    // for(int d=0;d<=30;d++){
    //   //cout<<d<<" "<<flush;
    //   used.clear();
    //   // start地点をセット
    //   for(int i=0;i<3;i++){
    //     for(int j=0;j<3;j++){
    //       if(i==sy&&j==sx){
    //         field[i][j]=pii(-1,-1);
    //         fieldMask=setMask(fieldMask,i*3+j,6);
    //       }
    //       else{
    //         field[i][j]=pii(2,0);
    //         fieldMask=setMask(fieldMask,i*3+j,toVal(2,0));
    //       }
    //     }
    //   }
    //   int cnt=0;
    //   for(int i=0;i<3;i++)
    //     for(int j=0;j<3;j++)
    //       cnt+=(field[i][j].first!=goal[i][j]);
    //   used.insert(fieldMask);
    //   res=iddfs(0,d,sy,sx,cnt);
    //   if(res!=-1){
    //     res=d;
    //     break;
    //   }
    // }
    //cout<<endl;
    //cout<<res<<endl<<flush;
    //cout<<res<<endl;
  }
  return 0;
}

Measured memory_bytes: 1220