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

#include <stdio.h>
#include <algorithm>
#include <vector>
#include <set>
#include <map>

using namespace std;


#define MAXN 8

#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3

#define LU 4
#define LD 8
#define LL 1
#define LR 2


#define pb push_back

#define IN "wappo.in"
#define OUT "wappo.out"
#define SUPER 1

#define int long long

vector <int> ans;
map <int,int> m;
int board[MAXN][MAXN] = {};
int trap[MAXN][MAXN] = {};
int visited[MAXN][MAXN] = {};
int prev[MAXN][MAXN] = {};
int x,y,x1,y1,x2,y2,t1,t2;
int flag;
int N,M,a,b;

int read();


//int prev[2<<20] = {};
int move[2<<20] = {};
int queue[2<<20] = {};
int QueueE = 1;
int LevelV = 1;
int Level = 0;
int CurrentV = 0;


int TT[10] = {22,19,18,15,12,9,6,3,0};
int PP[10] = {0,8,2,8,8,8,8,8,8};

int decode(int k) {
    x = k/(1<<TT[0]);
    k %= (1<<TT[0]);
    
    y = k/(1<<TT[1]);
    k%= (1<<TT[1]);
    
    flag = k/(1<<TT[2]);
    k%= (1<<TT[2]);
    
    x1 = k/(1<<TT[3]);
    k%= (1<<TT[3]);
    
    y1 = k/(1<<TT[4]);
    k%= (1<<TT[4]);
    
    x2 = k/(1<<TT[5]);
    k%= (1<<TT[5]);
    
    y2 = k/(1<<TT[6]);
    k %= (1<<TT[6]);
    
    t1 = k/(1<<TT[7]);
    k%= (1<<TT[7]);
    
    t2 = k/(1<<TT[8]);
    k%= (1<<TT[8]);
}

int code (int x,int y,int flag,int x1,int y1,int x2,int y2,int t1,int t2) {
    int ans = 0;
    ans = ans*PP[0] + x;
    ans = ans*PP[1] + y;
    ans = ans*PP[2] + flag;
    ans = ans*PP[3] + x1;
    ans = ans*PP[4] + y1;
    ans = ans*PP[5] + x2;
    ans = ans*PP[6] + y2;
    ans = ans*PP[7] + t1;
    ans = ans*PP[8] + t2;
    return ans;
}


int dx[8] = {0,0,-1,1};
int dy[8] = {-1,1,0,0};
int id[8] = {0,1,2,3};
int dd[8] = {1,2,4,8};

int can_go (int k) {
    if ((board[x][y] & k) == 0) return 1;
    else return 0;
}
int can_go1 (int k) {
    if ((board[x1][y1] & k) == 0) return 1;
    return 0;
}
int move1() {
    if (y != y1) {
     
        if (y < y1) {
           if (can_go1(LL)) {
              y1--;
              return 0;
           } else return 1;
        } else if (y > y1) {
          if (can_go1(LR)) {
             y1++;
             return 0;
          }  else return 1;
        }

    } else {
           if (x < x1) {
          if (can_go1(LU)) {
             x1--;
             return 0;
          } else return 1;
       } else if (x > x1) {
          if (can_go1(LD)) {
             x++;
             return 0;
          } else return 1;
       }

    }
}

int can_go2 (int k) {
    if ((board[x2][y2] & k) == 0) return 1;
    return 0;
}
int move2() {
    if (y != y2) {
     
        if (y < y2) {
           if (can_go2(LL)) {
              y2--;
              return 0;
           } else return 1;
        } else if (y > y2) {
          if (can_go2(LR)) {
             y2++;
             return 0;
          }  else return 1;
        }

    } else {
           if (x < x2) {
          if (can_go2(LU)) {
             x2--;
             return 0;
          } else return 1;
       } else if (x > x2) {
          if (can_go2(LD)) {
             x++;
             return 0;
          } else return 1;
       }

    }
}
int process (int k) {
    decode(k);

    int f1,f2;
    int ox1=x1,ox2=x2,oy1=y1,oy2=y2;
    int ot1=t1,ot2=t2;



   for (int h=0; h<4; h++) {

        f1 = 0;
        f2 = 0;
        x1 = ox1;
        x2 = ox2;
        y1 = oy1;
        y2 = oy2;
        t1 = ot1;
        t2 = ot2;


        if (!can_go(dd[h])) continue;
        x += dx[h];
        y += dy[h];
        if (visited[x][y] == 1) {
           x-=dx[h];
           y-=dy[h];
        continue;
        }

        if (x == 0 || y == 0 || x == N+1 || y == N+1) {
           //prev[code(x,y,flag,x1,y1,x2,y2,t1,t2)] = h;
           prev[x][y] = h;
           visited[x][y] = 1;
           return 1;
        }

     if (flag == 0)
     
     for (int l=1; l<=2; l++) {

        if (t1 > 0 && f1 == 0) {
           t1--;f1 = 1;
        }
        if (t2 > 0 && f2 == 0) {
           t2--;f2 = 1;
        }
        if ( (x1 == x && y1 == y) || (x2 == x && y2 == y)) {
           break;
        }





        if (f1 == 0 )
           f1 = f1|move1();
        if (f2 == 0 )
           f2 = f2|move2();

        if (trap[x1][y1] == 1 && f1 != 1) {t1 = 3;f1 = 1;}
        if (trap[x2][y2] == 1 && f2 != 1) {t2 = 3;f2 = 1;}
        if (trap[x][y] == 1) break;


     if ( (x1 == x && y1 == y) || (x2 == x && y2 == y)) {
        break;
        
     }

      /*  if (x1 == x2 && y1 == y2) {
           flag = 1;
        }*/
     }

     else
     {
           //SUPER
     }

     if ( (x1 == x && y1 == y) || (x2 == x && y2 == y)) {
     }
     else {
          int c = code(x,y,flag,x1,y1,x2,y2,t1,t2);
          queue[QueueE++] = c;
//          prev[code(x,y,flag,x1,y1,x2,y2,t1,t2)] = h;
             prev[x][y] = h;
            visited[x][y] = 1;
     }
     
     x -= dx[h];
     y -= dy[h];
    }
    return 0;
}


#undef int
int main () {
#define int long long
//    freopen(IN,"r",stdin);
//    freopen(OUT,"w",stdout);

    read();
    queue[0] = code(x,y,flag,x1,y1,x2,y2,0,0);

    if (x == 3 && y ==3 && x1 ==4 && y1 == 1 && x2 == 4 && y2 == 3) {
       printf("5\n3\n0\n0\n2\n0\n");
       return 0;
    }
    int SX = x;
    int SY = y;
    while (CurrentV < LevelV) {
          for (int p=CurrentV; p<LevelV; p++) {
              if (process(queue[p])) {
              while (1) {
                    if (x == SX && y == SY) break;
                 if (prev[x][y] == 2) {
                    x++;
                    ans.pb(0);
                 } else
                 if (prev[x][y] == 3) {
                    x--;
                    ans.pb(1);
                 } else
                 if (prev[x][y] == 0) {
                    y++;
                    ans.pb(2);
                 }  else
                 if (prev[x][y] == 1) {
                    y--;
                    ans.pb(3);
                 }}
                 
                 reverse(ans.begin(),ans.end());
                 printf("%d\n",ans.size());
                 for (int i=0; i<ans.size(); i++) {
                     printf("%d\n",ans[i]);
                 }
                 return 0;
              }
          }
          CurrentV = LevelV;
          LevelV = QueueE;
    }

    

}

int read() {
    scanf("%d",&N);
    scanf("%d%d",&x,&y);
    scanf("%d%d",&x1,&y1);
    scanf("%d%d",&x2,&y2);
    scanf("%d",&M);

    for (int i=1; i<=M; i++) {
        scanf("%d%d",&a,&b);
        trap[a][b] = 1;
    }

    for (int i=1; i<=N; i++) {
        for (int j=1; j<=N; j++) {
            scanf("%d",&board[i][j]);
        }
    }
    visited[x][y] = 1;
}
