/*
LANG: C++
TASK: wappo
*/

#include <cstdio>
#include <cstdlib>

const int MAXN = 8;
/*
struct qel {
    short pos;
    short pen;
    qel (short a, short b):pos(a), pen(b) {}
};
*/
struct state {
    int hc, hr;
    int ch1c, ch1r, p1;
    int ch2c, ch2r, p2;
};

void prnt (state beg1) {
//    printf ("%d %d %d %d %d %d %d %d\n", beg1.hr, beg1.hc, beg1.ch1r, beg1.ch1c, beg1.ch2r, beg1.ch2c, beg1.p1, beg1.p2);
}

int difx [] = {-1, 1, 0, 0};
int dify [] = {0, 0, -1, 1};

int code (state s) {
    unsigned res = 0;

    res += s.hc-1;
    res *= 6;
    res += s.hr-1;
    res *= 6;
    res += s.ch1c-1;
    res *= 6;
    res += s.ch1r-1;
    res *= 6;
    res += s.ch2c-1;
    res *= 6;
    res += s.ch2r-1;

    res |= ((s.p1 * 4 + s.p2) << 16);
    return res;
}

state decode (int a) {
    state ret;

    ret.p2 = (a >> 16) % 4;
    ret.p1 = ((a >> 16) / 4) % 4;
    a &= ((1<<16)-1);
    
    ret.ch2r = a % 6 + 1; a /= 6;
    ret.ch2c = a % 6 + 1; a /= 6;
    ret.ch1r = a % 6 + 1; a /= 6;
    ret.ch1c = a % 6 + 1; a /= 6;
    ret.hr = a % 6 + 1; a /= 6;
    ret.hc = a % 6 + 1; a /= 6;

    return ret;
}

int N;
char map[MAXN][MAXN];
bool trap[MAXN][MAXN];

state beg;

int T;

int mc;
int *move = new int [1000000];

bool if_wall (int r, int c, int k) {
//    printf ("if_wall - %d %d %d =>", r, c, k);
    switch (k) {
    case 0: k = 4; break;
    case 1: k = 8; break;
    case 2: k = 1; break;
    case 3: k = 2; break;
    }
//    printf (" (%d)%d\n", k, map[r][c] & k);
    return (map[r][c] & k);
}

int can_exit (state s) {
    if (s.hr == 1 && !if_wall (s.hr, s.hc, 0))
        return 0;
    if (s.hc == 1 && !if_wall (s.hr, s.hc, 2))
        return 2;
    if (s.hc == N && !if_wall (s.hr, s.hc, 3))
        return 3;
    if (s.hr == N && !if_wall (s.hr, s.hc, 1))
            return 1;
    return -1;
}

int genmove (int r, int c) {
//    printf ("gen move -> %d %d", r, c);
    for (int i = 0; i < 4; ++i)
        if (difx[i] == r && dify[i] == c) {
//            printf (" => %d\n", i);
            return i;
        }
//    printf ("UJAST!!!\n");
    return -1;
}

int movemonsters (state s) {
    bool f1;
    int dc,dr, m;
    if (s.ch1r != s.ch2r || s.ch1c != s.ch2c) {//2 monsters
        for (int br = 0; br < 2; ++br) {
//MUST HAVE INDENT  |V
        if (s.p1 == 0) {
            f1 = 1;
            if (s.ch1c != s.hc) {
                dc = (s.hc - s.ch1c) / abs (s.hc - s.ch1c);
                m = genmove (0, dc);
                if (!if_wall(s.ch1r, s.ch1c, m)) {
                    s.ch1r += difx[m];
                    s.ch1c += dify[m];

                    if (trap[s.ch1r][s.ch1c]) {
                        s.p1 = 4;
                    }
                    if (s.hr == s.ch1r && s.hc == s.ch1c)
                        return -1;//cought
                    f1 = 0;
                }
            }
            if (s.ch1r != s.hr && f1) {
                dr = (s.hr - s.ch1r) / abs (s.hr - s.ch1r);
                m = genmove (dr, 0);
                if (!if_wall(s.ch1r, s.ch1c, m)) {
                    s.ch1r += difx[m];
                    s.ch1c += dify[m];

                    if (trap[s.ch1r][s.ch1c]) {
                        s.p1 = 4;
                    }
                    if (s.hr == s.ch1r && s.hc == s.ch1c)
                        return -1;//cought
                }
            }
        }
        if (s.p2 == 0) {
            f1 = 1;
            if (s.ch2c != s.hc) {
                dc = (s.hc - s.ch2c) / abs (s.hc - s.ch2c);
                m = genmove (0, dc);
                if (!if_wall(s.ch2r, s.ch2c, m)) {
                    s.ch2r += difx[m];
                    s.ch2c += dify[m];

                    prnt(s);

                    if (s.ch2r == s.ch1r && s.ch2c == s.ch1c) {
                        return code (s);//make supermonster -> no more moves
                    }
                    if (trap[s.ch2r][s.ch2c]) {
                        s.p2 = 4;
                    }

                    if (s.hr == s.ch2r && s.hc == s.ch2c)
                        return -1;//cought
                    f1 = 0;
                }
            }
            if (s.ch2r != s.hr && f1) {
                dr = (s.hr - s.ch2r) / abs (s.hr - s.ch2r);
                m = genmove (dr, 0);
                if (!if_wall(s.ch2r, s.ch2c, m)) {
                    s.ch2r += difx[m];
                    s.ch2c += dify[m];

                    if (s.ch2r == s.ch1r && s.ch2c == s.ch1c) {
                        return code (s);//make supermonster -> no more moves
                    }
                    if (trap[s.ch2r][s.ch2c]) {
                        s.p2 = 4;
                    }
                    if (s.hr == s.ch2r && s.hc == s.ch2c)
                        return -1;//cought
                }
            }
        }
//MUST HAVE INDENT ^
        }
        if (s.p1 != 0)
            --s.p1;
        if (s.p2 != 0)
            --s.p2;
    } else {//super monster
        for (int br = 0; br < 3; ++br) {
            f1 = 1;
            if (s.ch1c != s.hc) {
                dc = (s.hc - s.ch1c) / abs (s.hc - s.ch1c);
                m = genmove (0, dc);
                if (!if_wall(s.ch1r, s.ch1c, m)) {
                    s.ch1r += difx[m];
                    s.ch1c += dify[m];

                    if (s.hr == s.ch1r && s.hc == s.ch1c)
                        return -1;//cought
                    f1 = 0;
                }
            }
            if (s.ch1r != s.hr && f1) {
                dr = (s.hr - s.ch1r) / abs (s.hr - s.ch1r);
                m = genmove (dr, 0);
                if (!if_wall(s.ch1r, s.ch1c, m)) {
                    s.ch1r += difx[m];
                    s.ch1c += dify[m];

                    if (s.hr == s.ch1r && s.hc == s.ch1c)
                        return -1;//cought
                }
            }
            s.ch2r = s.ch1r; s.ch2c = s.ch2c;//remain supermonster :)
        }
    }
    return code (s);
}

int bfs () {
    int p1 =0, p2 =1, p3 =0;
    int *queue = new int [1100000];
    bool *used = new bool [1100000];
    int *prev = new int [1100000];//the index of the previous one (in queue)

    queue[p3++] = code (beg);//start
    prev[0] = -1;

    int i, k;
    int p;
    state crnt;
    
    while (p1 != p2) {
        for (i = p1; i < p2; ++i) {
            crnt = decode(queue[i]);
            prnt (crnt);
            if (can_exit(crnt) != -1) {
                move[mc++] = can_exit (crnt);
                goto end;
            }

            for (k = 0; k < 4; ++k) {
                if (!if_wall(crnt.hr, crnt.hc, k) && !trap[crnt.hr + difx[k]][crnt.hc + dify[k]] &&
                !(crnt.ch1c == crnt.hc + dify[k]&& crnt.ch1r == crnt.hr + difx[k]) &&
                !(crnt.ch2c == crnt.hc + dify[k] && crnt.ch2r == crnt.hr + difx[k])) {

                    crnt.hr += difx[k];
                    crnt.hc += dify[k];
                    if ((p = movemonsters (crnt)) != -1 && !used[p]) {
                        prnt (decode(p));

                        used[p] = 1;
                        queue[p3] = p;
                        prev[p3++] = i;
                    }

                    crnt.hr -= difx[k];
                    crnt.hc -= dify[k];
                }
            }
        }
        p1 = p2;
        p2 = p3;
    }
    
    
    end:;
    
    state now, pr;
    for (i; prev[i] != -1; i = prev[i]) {
        now = decode (queue[i]);
        pr = decode (queue[prev[i]]);
        move[mc++] = genmove (now.hr - pr.hr, now.hc - pr.hc);
    }

}


int main () {
    scanf ("%d%d%d%d%d%d%d%d", &N, &beg.hr, &beg.hc, &beg.ch1r, &beg.ch1c, &beg.ch2r, &beg.ch2c, &T);

    int i, j;
    int a, b;
    for (i = 0; i < T; ++i) {
        scanf ("%d%d", &a, &b);
        trap[a][b] = 1;
    }
    
    for (i = 1; i <= N; ++i)
        for (j = 1; j <= N; ++j) {
            scanf ("%d", &a);
            map[i][j] = a;
        }
    beg.p1 = 0;
    beg.p2 = 0;

    bfs ();

    printf ("%d\n", mc);
    for (i = mc-1; i >= 0; --i)
        printf ("%d\n", move[i]);

    return 0;
}
