/*
TASK:lab101
LANG:C++
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

const int MAX_X = 11;
const int MAX_Y = 6;
const int MAX_SWITCH_COUNT = 33;

const int SQUARE_EMPTY = 0;
const int SQUARE_WALL  = 1;

const int RESOLUTION_WIN = 0;
const int RESOLUTION_LOOSE = 1;
const int RESOLUTION_DRAW = 2;
const int RESOLUTION_INVALID = 3; // for situations that result of impossible moves

struct Point {
	int x,y;
};

char initial_map[MAX_X][MAX_Y];

int bit[MAX_X][MAX_Y]; // the bit for this switchable square
bool bit_assigned[MAX_X][MAX_Y];

Point switch_target[MAX_SWITCH_COUNT];
bool switch_here[MAX_X][MAX_Y];
int switch_number[MAX_X][MAX_Y];
bool switched_square[MAX_X][MAX_Y];
int switch_count;

int size_x,size_y;
int player1_start_x,player1_start_y;
int player2_start_x,player2_start_y;
int exit_x,exit_y;

//
// <situation array>[Player_to_move_X][Player_to_move_Y][Other_player_X][other_player_Y][mask]
// visited - if situation has or is currently being processed
// resolution - if situation is a winning, losing or draw situation for current to-move player
// mask - a bit mask with the status of changing squares ( 0 - passable, 1 - wall)
//
// For the purpose of the algorithm players will not be allowed to repeat situations since this
// can make the game infinte hence a move that will create a visited situation will not be 
// considered valid
//
bool visited[MAX_X][MAX_Y][MAX_X][MAX_Y][1024];
char resolution[MAX_X][MAX_Y][MAX_X][MAX_Y][1024];

void load()
{
	FILE *fin;

	//fin = fopen("lab101.in","r");
	fin = stdin;

	fscanf(fin,"%d%d",&size_y,&size_x);	
	int x,y;	
	int i;
	for (y=0;y<size_y;y++) {
		for (x=0;x<size_x;x++) {			
			fscanf(fin,"%d",&i);				
			initial_map[x][y] = i;			
			//printf("(%d,%d)%d ",x,y,initial_map[x][y]);
		}
		//printf("\n");
	}

	fscanf(fin,"%d",&switch_count);	
	int next_bit = 0;
	for (i=0;i<switch_count;i++) {
		int switch_x,switch_y;
		int target_x,target_y;

		fscanf(fin,"%d%d%d%d",&switch_y,&switch_x,&target_y,&target_x);
		switch_x--;
		switch_y--;
		target_x--;
		target_y--;
		switch_target[i].x = target_x;
		switch_target[i].y = target_y;
		switch_here[switch_x][switch_y] = true;
		switch_number[switch_x][switch_y] = i;

		switched_square[target_x][target_y] = true;
		if (bit[target_x][target_y] == false) {
			bit[target_x][target_y] = next_bit;
			next_bit++;
		}
	}

	fscanf(fin,"%d%d%d%d%d%d",&player1_start_y,&player1_start_x,
			          &player2_start_y,&player2_start_x,
				  &exit_y,&exit_x);
	player1_start_x--;
	player1_start_y--;
	player2_start_x--;
	player2_start_y--;
	exit_x--;
	exit_y--;

	fclose(fin);		
}

inline void set_bit(int *mask,int bit)
{
	(*mask) = (*mask) | (1 << bit);
}

inline void clear_bit(int *mask,int bit)
{
	(*mask) = (*mask) & ( 1023 - (1 << bit));
}

inline char get_bit(int mask,int bit)
{
	return ( mask & ( 1 << bit) ) > 0 ? true : false;
}

int get_initial_mask()
{
	int mask = 0;
	int i;

	for (i=0;i<switch_count;i++)
		if (initial_map[switch_target[i].x][switch_target[i].y] == SQUARE_WALL)
			set_bit(&mask,i);

	return mask;
}

inline bool situation_valid(int mover_x,int mover_y,int waiter_x,int waiter_y,int cur_mask) 
{
	// Check argument ranges
	if (mover_x < 0)
		return false;
	if (mover_y < 0)
		return false;
	if (waiter_x < 0)
		return false;
	if (waiter_y < 0)
		return false;
	if (cur_mask < 0)
		return false;
	if (mover_x >= size_x)
		return false;
	if (mover_y >= size_y)
		return false;
	if (waiter_x >= size_x)
		return false;
	if (waiter_y >= size_y)
		return false;
	if (cur_mask >= 1024)
		return false;
	
	// Check that squares are passable
	if (!switched_square[mover_x][mover_y] && initial_map[mover_x][mover_y] == SQUARE_WALL)
		return false;
	if (!switched_square[waiter_x][waiter_y] && initial_map[waiter_x][waiter_y] == SQUARE_WALL)
		return false;

	if (switched_square[mover_x][mover_y] && 
	    get_bit(cur_mask,bit[mover_x][mover_y]) == 1)
		return false;
	if (switched_square[waiter_x][waiter_y] && 
	    get_bit(cur_mask,bit[mover_x][mover_y]) == 1)
		return false;

	return true;
}

int do_solve(int mover_x,int mover_y,int waiter_x,int waiter_y,int cur_mask) 
{
	if (!situation_valid(mover_x,mover_y,waiter_x,waiter_y,cur_mask)) 
		return RESOLUTION_INVALID;
	
	if (visited[mover_x][mover_y][waiter_x][waiter_y][cur_mask])
		return resolution[mover_x][mover_y][waiter_x][waiter_y][cur_mask];

	visited[mover_x][mover_y][waiter_x][waiter_y][cur_mask] = true;

	if (waiter_x == exit_x && waiter_y == exit_y) {
		resolution[mover_x][mover_y][waiter_x][waiter_y][cur_mask] = RESOLUTION_LOOSE;
		return RESOLUTION_LOOSE;
	}

	bool found_winning_situation = false;	
	bool found_draw_situation    = false;

	int res;

	int mover_new_x;
	int mover_new_y;
	
	// move	right
	mover_new_x = mover_x+1;
	mover_new_y = mover_y;
	{
		res = do_solve(waiter_x,waiter_y,mover_new_x,mover_new_y,cur_mask);
		if (res == RESOLUTION_WIN)
			found_winning_situation = true;
		if (res == RESOLUTION_LOOSE) {
			resolution[mover_x][mover_y][waiter_x][waiter_y][cur_mask] = RESOLUTION_WIN;
			return RESOLUTION_WIN;			
		}
		if (res == RESOLUTION_DRAW)
			found_draw_situation = true;
	}

	// move	left
	mover_new_x = mover_x-1;
	mover_new_y = mover_y;
	{
		res = do_solve(waiter_x,waiter_y,mover_new_x,mover_new_y,cur_mask);
		if (res == RESOLUTION_WIN)
			found_winning_situation = true;
		if (res == RESOLUTION_LOOSE) {
			resolution[mover_x][mover_y][waiter_x][waiter_y][cur_mask] = RESOLUTION_WIN;
			return RESOLUTION_WIN;			
		}
		if (res == RESOLUTION_DRAW)
			found_draw_situation = true;
	}

	// move	down
	mover_new_x = mover_x;
	mover_new_y = mover_y+1;
	{
		res = do_solve(waiter_x,waiter_y,mover_new_x,mover_new_y,cur_mask);
		if (res == RESOLUTION_WIN)
			found_winning_situation = true;
		if (res == RESOLUTION_LOOSE) {
			resolution[mover_x][mover_y][waiter_x][waiter_y][cur_mask] = RESOLUTION_WIN;
			return RESOLUTION_WIN;			
		}
		if (res == RESOLUTION_DRAW)
			found_draw_situation = true;
	}

	// move	up
	mover_new_x = mover_x;
	mover_new_y = mover_y-1;
	{
		res = do_solve(waiter_x,waiter_y,mover_new_x,mover_new_y,cur_mask);
		if (res == RESOLUTION_WIN)
			found_winning_situation = true;
		if (res == RESOLUTION_LOOSE) {
			resolution[mover_x][mover_y][waiter_x][waiter_y][cur_mask] = RESOLUTION_WIN;
			return RESOLUTION_WIN;			
		}
		if (res == RESOLUTION_DRAW)
			found_draw_situation = true;
	}
	
	//flip the switch
	if (switch_here[mover_x][mover_y]) {
		int target_x = switch_target[switch_number[mover_x][mover_y]].x;
		int target_y = switch_target[switch_number[mover_x][mover_y]].y;
		mover_new_x = mover_x;
		mover_new_y = mover_y;

		if (!(target_x == waiter_x && target_y == waiter_y)) {
			int bit_idx = bit[target_x][target_y];
			int cur_status = get_bit(cur_mask,bit_idx);
			int new_mask;

			if (cur_status == 1) {
				new_mask = cur_mask;
				clear_bit(&new_mask,bit_idx);

				res = do_solve(waiter_x,waiter_y,mover_new_x,mover_new_y,new_mask);
				if (res == RESOLUTION_WIN)
					found_winning_situation = true;
				if (res == RESOLUTION_LOOSE) {
					resolution[mover_x][mover_y][waiter_x][waiter_y][cur_mask] = RESOLUTION_WIN;
					return RESOLUTION_WIN;			
				}
				if (res == RESOLUTION_DRAW)
					found_draw_situation = true;

			} else {
				new_mask = cur_mask;
				set_bit(&new_mask,bit_idx);

				res = do_solve(waiter_x,waiter_y,mover_new_x,mover_new_y,new_mask);
				if (res == RESOLUTION_WIN)
					found_winning_situation = true;
				if (res == RESOLUTION_LOOSE) {
					resolution[mover_x][mover_y][waiter_x][waiter_y][cur_mask] = RESOLUTION_WIN;
					return RESOLUTION_WIN;			
				}
				if (res == RESOLUTION_DRAW)
					found_draw_situation = true;
			}
		}

	}

	//do nothing
	mover_new_x = mover_x;
	mover_new_y = mover_y;
	res = do_solve(waiter_x,waiter_y,mover_new_x,mover_new_y,cur_mask);
	if (res == RESOLUTION_WIN)
		found_winning_situation = true;
	if (res == RESOLUTION_LOOSE) {
		resolution[mover_x][mover_y][waiter_x][waiter_y][cur_mask] = RESOLUTION_WIN;
		return RESOLUTION_WIN;			
	}
	if (res == RESOLUTION_DRAW)
		found_draw_situation = true;

	if (found_draw_situation || !found_winning_situation) {
		resolution[mover_x][mover_y][waiter_x][waiter_y][cur_mask] = RESOLUTION_DRAW;
		return RESOLUTION_DRAW;			
	}
	if (found_winning_situation) {
		resolution[mover_x][mover_y][waiter_x][waiter_y][cur_mask] = RESOLUTION_LOOSE;
		return RESOLUTION_LOOSE;			
	}

	return resolution[mover_x][mover_y][waiter_x][waiter_y][cur_mask];
}

int solve()
{
	int mask = get_initial_mask();

	int res = do_solve(player1_start_x,player1_start_y,
	  	           player2_start_x,player2_start_y,
		           mask);
	
	if (res == RESOLUTION_WIN)
		return 1;
	if (res == RESOLUTION_LOOSE)
		return 2;
	return 0;
}

void save(int result)
{
	printf("%d\n",result);
}

void print_10_bits(int mask)
{
	int i;

	for (i=9;i>=0;i--)
		printf("%d ",get_bit(mask,i));
	printf("\n");
}

void test_bit_ops()
{
	int mask;
	int i;
	
	mask = 1023;
	print_10_bits(mask);

	mask = 127;
	print_10_bits(mask);

	clear_bit(&mask,0);
	clear_bit(&mask,1);	
	clear_bit(&mask,2);
	clear_bit(&mask,3);
	clear_bit(&mask,3);
	clear_bit(&mask,3);
	print_10_bits(mask);

	set_bit(&mask,2);
	set_bit(&mask,2);
	set_bit(&mask,2);
	print_10_bits(mask);
	set_bit(&mask,1);
	print_10_bits(mask);
	
	exit(0);
}

int main()
{
	//test_bit_ops();	

	memset(switch_here,0,sizeof(switch_here));
	memset(visited,0,sizeof(visited));
	memset(bit_assigned,0,sizeof(bit_assigned));
	memset(switched_square,0,sizeof(switched_square));

	load();
	save(solve());

	return 0;
}