Problem: Let's play a puzzle using eight cubes placed on a 3 × 3 board leaving one empty square.

Faces of cubes are painted with three colors. As a puzzle step, you can roll one of the cubes to the adjacent empty square. Your goal is to make the specified color pattern visible from above by a number of such steps.

The rules of this puzzle are as follows.

1. Coloring of Cubes: All the cubes are colored in the same way as shown in Figure 3. The opposite faces have the same color.

<image>

Figure 3: Coloring of a cube



2. Initial Board State: Eight cubes are placed on the 3 × 3 board leaving one empty square. All the cubes have the same orientation as shown in Figure 4. As shown in the figure, squares on the board are given x and y coordinates, (1, 1), (1, 2), .. ., and (3, 3). The position of the initially empty square may vary.

<image>

Figure 4: Initial board state



3. Rolling Cubes: At each step, we can choose one of the cubes adjacent to the empty square and roll it into the empty square, leaving the original position empty. Figure 5 shows an example.

<image>

Figure 5: Rolling a cube



4. Goal: The goal of this puzzle is to arrange the cubes so that their top faces form the specified color pattern by a number of cube rolling steps described above.



Your task is to write a program that finds the minimum number of steps required to make the specified color pattern from the given initial state.



Input

The input is a sequence of datasets. The end of the input is indicated by a line containing two zeros separated by a space. The number of datasets is less than 16. Each dataset is formatted as follows.


x y
F11 F21 F31
F12 F22 F32
F13 F23 F33


The first line contains two integers x and y separated by a space, indicating the position (x, y) of the initially empty square. The values of x and y are 1, 2, or 3.

The following three lines specify the color pattern to make. Each line contains three characters F1j, F2j, and F3j, separated by a space. Character Fij indicates the top color of the cube, if any, at position (i, j) as follows:


B: Blue
W: White
R: Red
E: the square is Empty.


There is exactly one 'E' character in each dataset.

Output

For each dataset, output the minimum number of steps to achieve the goal, when the goal can be reached within 30 steps. Otherwise, output "-1" for the dataset.

Example

Input

1 2
W W W
E W W
W W W
2 1
R B W
R W W
E W W
3 3
W B W
B R E
R B R
3 3
B W R
B W R
B E R
2 1
B B B
B R B
B R E
1 1
R R R
W W W
R R E
2 1
R R R
B W B
R R E
3 2
R R R
W E W
R R R
0 0


Output

0
3
13
23
29
30
-1
-1

Solution (in CPP):

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

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define IINF (INT_MAX)
#define LEN 2

using namespace std;

typedef long long ll;

enum FACE { TOP, BOTTOM, FRONT, BACK, LEFT, RIGHT };
template <class T>
class Dice {
public:
  Dice() {
    id[TOP] = 0; id[FRONT] = 1; id[LEFT] = 2;
    id[RIGHT] = 3; id[BACK] = 4; id[BOTTOM] = 5;
  }
  T& operator[] (FACE f) { return var[id[f]]; }
  const T& operator[] (FACE f) const { return var[id[f]]; }
  bool operator==(const Dice<T>& b) const {
    const Dice<T> &a = *this;
    return a[TOP] == b[TOP] && a[BOTTOM] == b[BOTTOM] &&
      a[FRONT] == b[FRONT] && a[BACK] == b[BACK] &&
      a[LEFT] == b[LEFT] && a[RIGHT] == b[RIGHT];
  }
  void roll_x() { roll(TOP, BACK, BOTTOM, FRONT); }
  void roll_y() { roll(TOP, LEFT, BOTTOM, RIGHT); }
  void roll_z() { roll(FRONT, RIGHT, BACK, LEFT); }
  vector<Dice> all_rolls() {
    vector<Dice> ret;
    for (int k = 0; k < 6; (k&1?roll_y():roll_x()),++k)
      for (int i = 0; i < 4; roll_z(), ++i)
        ret.push_back(*this);
    return ret;
  }
  bool equivalent_to(const Dice& di) {
    for (int k = 0; k < 6; (k&1?roll_y():roll_x()),++k)
      for (int i = 0; i < 4; roll_z(), ++i)
        if (*this == di) return true;
    return false;
  }
private:
  void roll(FACE a, FACE b, FACE c, FACE d) {
    T tmp = id[a];
    id[a] = id[b]; id[b] = id[c];
    id[c] = id[d]; id[d] = tmp;
  }
  T var[6];
  int id[6];
};

FACE face[] = {TOP,BOTTOM,FRONT,BACK,LEFT,RIGHT};

int around[6][4] = 
  {
    {1,2,4,3},
    {0,3,5,2},
    {0,1,5,4},
    {0,4,5,1},
    {0,2,5,3},
    {1,3,4,2}
  };


Dice<int> makeDice(int top,int front){
  Dice<int> ret;
  ret[TOP] = top, ret[BOTTOM] = 5-top;
  ret[FRONT] = front, ret[BACK] = 5-front;
  int idx = IINF;
  for(int i=0;i<4;i++){
    if(around[top][i] == front){
      idx = i+1;
      break;
    }
  }
  assert(idx != IINF);
  idx %= 4;
  ret[RIGHT] = around[top][idx], ret[LEFT] = 5-around[top][idx];
  return ret;
}

inline int toInt(char c){ return ((c=='B')?0:((c=='E')?1:((c=='R')?2:3))); }
char F[3][3];
char initial_color[] = {'W','W','R','R','B','B'};
int mincost;
int dx[] = {1,0,-1,0}; // R, B, L, T
int dy[] = {0,1,0,-1};

inline void swap_dice(Dice<char> dice[3][3],int x1,int y1,int x2,int y2,int type){
  if( type == 0 ) rep(i,3)dice[y2][x2].roll_y();
  if( type == 1 ) rep(i,3)dice[y2][x2].roll_x();
  if( type == 2 ) dice[y2][x2].roll_y();
  if( type == 3 ) dice[y2][x2].roll_x();
  swap(dice[y1][x1],dice[y2][x2]);
}

inline int finish(Dice<char> dice[3][3]){
  int diff = 0;
  rep(i,3)rep(j,3)if( dice[i][j][TOP] != F[i][j] ) diff++;
  return diff;
}

void dfs(Dice<char> dice[3][3],int x,int y,int cost,int pre){

  if( cost >= mincost) return;

  int tmp;
  if( ( tmp = finish(dice) ) == 0 ){
    mincost = min(mincost,cost);
    return;
  }

  if( tmp )tmp--;
  if( cost + tmp >= mincost ) return;

  rep(i,4){
    if( i == pre ) continue;
    int nx = x + dx[i], ny = y + dy[i];
    if( !( 0 <= nx && nx < 3 && 0 <= ny && ny < 3 ) ) continue;
    swap_dice(dice,x,y,nx,ny,i);
    dfs(dice,nx,ny,cost+1,(i+2)%4);
    swap_dice(dice,nx,ny,x,y,(i+2)%4);
  }
}

int main(){

  int x,y;
  while(cin>>x>>y,x|y){
    x--,y--;
    mincost = 31;
    rep(i,3)rep(j,3)cin >> F[i][j];

    Dice<char> dice[3][3];
    rep(i,3)rep(j,3)rep(k,6)dice[i][j][face[k]] = initial_color[k];
    rep(k,6)dice[y][x][face[k]] = 'E';

    dfs(dice,x,y,0,-1);

    if( mincost == 31 ) puts("-1");
    else                printf("%d\n",mincost);

  }
  return 0;
}