#include <iostream>
#include <array>
#include <vector>
#include <set>
#include <unordered_set>
#include <map>
#include <queue>
#include <algorithm>
#include <cassert>
#define repeat_from(i,m,n) for (int i = (m); (i) < (n); ++(i))
#define repeat(i,n) repeat_from(i,0,n)
#define repeat_from_reverse(i,m,n) for (int i = (n)-1; (i) >= (m); --(i))
#define repeat_reverse(i,n) repeat_from_reverse(i,0,n)
#define dump(x)  cerr << #x << " = " << (x) << endl
#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl
using namespace std;

// Wn R   Wr B
//   BWB    RWR
//    R      B
// Bn R   Br W
//   WBW    RBR
//    R      W
// Rn W   Rr B
//   BRB    WRW
//    W      B
const char Wn = 'W';
const char Wr = 'w';
const char Bn = 'B';
const char Br = 'b';
const char Rn = 'R';
const char Rr = 'r';
const char E  = 'E';
char next_tate(char dice) {
    return
        dice == Wn ? Rn :
        dice == Wr ? Br :
        dice == Bn ? Rr :
        dice == Br ? Wr :
        dice == Rn ? Wn :
        dice == Rr ? Bn : 0;
}
char next_yoko(char dice) {
    return
        dice == Wn ? Bn :
        dice == Wr ? Rr :
        dice == Bn ? Wn :
        dice == Br ? Rn :
        dice == Rn ? Br :
        dice == Rr ? Wr : 0;
}
struct state_t {
    char f[3][3];
    int8_t ey, ex;
    int8_t n;
    int8_t match;
};
bool equals_top(char const (& f)[3][3], char const (& g)[3][3]) {
    repeat (y,3) repeat (x,3) {
        if (toupper(f[y][x]) != toupper(g[y][x])) {
        // if (toupper(f[y][x] != toupper(g[y][x]))) {
            return false;
        }
    }
    return true;
}
const int dy[] = { -1, 1, 0, 0 };
const int dx[] = { 0, 0, -1, 1 };
uint32_t pack(char const (& f)[3][3]) {
    uint32_t z = 0;
    repeat (y,3) {
        repeat (x,3) {
            z *= 7;
            z +=
                f[y][x] == Wn ? 1 :
                f[y][x] == Wr ? 2 :
                f[y][x] == Bn ? 3 :
                f[y][x] == Br ? 4 :
                f[y][x] == Rn ? 5 :
                f[y][x] == Rr ? 6 : 0;
        }
    }
    return z;
}

int main() {
    while (true) {
        int sex, sey; cin >> sex >> sey;
        if (sex == 0 and sey == 0) break;
        -- sex; -- sey;
        char goal[3][3];
        repeat (y,3) repeat (x,3) cin >> goal[y][x];
        unordered_set<uint32_t> used;
        queue<state_t> que; {
            state_t s;
            repeat (y,3) repeat (x,3) s.f[y][x] = Wn;
            s.f[sey][sex] = E;
            s.ey = sey;
            s.ex = sex;
            s.n = 0;
            s.match = 0;
            repeat (y,3) repeat (x,3) if (goal[y][x] == s.f[y][x]) s.match += 1;
            que.push(s);
            used.insert(pack(s.f));
        }
        int result = -1;
        while (not que.empty()) {
            state_t s = que.front(); que.pop();
//repeat (y,3) {
//repeat (x,3) {
//cerr << s.f[y][x];
//}
//cerr << endl;
//}
//cerr << endl;
            if (equals_top(s.f, goal)) {
                result = s.n;
                break;
            }
            if (s.n == 30) continue;
            if (9 - s.match > 30 - s.n + 1) continue;
            repeat (i,4) {
                state_t t = s;
                t.ey = s.ey + dy[i];
                t.ex = s.ex + dx[i];
                if (t.ey < 0 or 3 <= t.ey or t.ex < 0 or 3 <= t.ex) continue;
                assert (s.f[s.ey][s.ex] == E);
                if (toupper(t.f[s.ey][s.ex]) == goal[s.ey][s.ex]) t.match -= 1;
                if (toupper(t.f[t.ey][t.ex]) == goal[t.ey][t.ex]) t.match -= 1;
                t.f[s.ey][s.ex] = dx[i] ? next_yoko(t.f[t.ey][t.ex]) : next_tate(t.f[t.ey][t.ex]);
                t.f[t.ey][t.ex] = E;
                if (toupper(t.f[s.ey][s.ex]) == goal[s.ey][s.ex]) t.match += 1;
                if (toupper(t.f[t.ey][t.ex]) == goal[t.ey][t.ex]) t.match += 1;
                t.n += 1;
                if (used.count(pack(t.f))) continue;
                que.push(t);
                used.insert(pack(t.f));
            }
        }
        cout << result << endl;
    }
    return 0;
}

Measured memory_bytes: 62044