/*
TASK:lab101
LANG:C++
*/

#include <map>
#include <cstdio>
#include <vector>
#include <algorithm>

typedef signed int ind;
typedef unsigned int hashval;
typedef unsigned int result;

void read_ind(ind& n) {std::scanf("%d", &n);}
void write_ind(const ind& n) {std::printf("%d", n);}
void read_result(result& n) {std::scanf("%u", &n);}
void write_result(const result& n) {std::printf("%u", n);}
void write(char *s) {std::printf("%s", s);}

const result unknown = 3;

class point
{
public:
	point() {}
	point(const ind& _x, const ind& _y) : x(_x), y(_y) {}

	ind x;
	ind y;
};

inline bool operator< (const point& a, const point& b)
{
	if (a.x != b.x) return a.x < b.x; else return a.y < b.y;
}

inline bool operator== (const point& a, const point& b)
{
	return a.x == b.x && a.y == b.y;
}

inline bool operator!= (const point& a, const point& b)
{
	return a.x != b.x || a.y != b.y;
}

class key
{
public:
	point loc;
	point target;
};

class state
{
public:
	point p1;
	point p2;
	std::vector<bool> keys;
};

class board
{
public:
	std::vector<std::vector<bool> > field;
	std::vector<key> keys;
	std::vector<point> targets;
	point finish;
};

hashval hash(const state& s)
{
	hashval f = 0;
	hashval p2 = 1;
	for (ind i = 0; i < (ind)s.keys.size(); i++)
	{
		f *= 2; p2 *= 2;
		if (s.keys[i]) f++;
	}
	f += s.p1.x*11*6*11*p2;
	f += s.p1.y*6*11*p2;
	f += s.p2.x*11*p2;
	f += s.p2.y*p2;

	return f;
}

result get_result(const state& s, board& b)
{
	static std::map<hashval, result> m;
	hashval h = hash(s);
	if (m.find(h) != m.end()) return m[h];
	m[h] = unknown;

	//std::printf("(%d, %d) (%d, %d)\n", s.p1.x, s.p1.y, s.p2.x, s.p2.y);

	if (s.p1 == b.finish) return m[h] = 1;
	if (s.p2 == b.finish) return m[h] = 2;

	bool enc0 = false; bool move_made = false;
	state ns = s;
	point p = ns.p1; ns.p1 = ns.p2; ns.p2 = p;
	state _ns = ns;

	ns = _ns; if (ns.p2.x && !b.field[ns.p2.x-1][ns.p2.y]) {ns.p2.x--; result r = get_result(ns, b); if (r == 2) return m[h] = 1; else if (r == 0) enc0 = true;  if (r != unknown) move_made = true;}
	ns = _ns; if (ns.p2.y && !b.field[ns.p2.x][ns.p2.y-1]) {ns.p2.y--; result r = get_result(ns, b); if (r == 2) return m[h] = 1; else if (r == 0) enc0 = true;  if (r != unknown) move_made = true;}
	ns = _ns; if (ns.p2.x < (ind)b.field.size()-1 && !b.field[ns.p2.x+1][ns.p2.y]) {ns.p2.x++; result r = get_result(ns, b); if (r == 2) return m[h] = 1; else if (r == 0) enc0 = true;  if (r != unknown) move_made = true;}
	ns = _ns; if (ns.p2.y < (ind)b.field[0].size()-1 && !b.field[ns.p2.x][ns.p2.y+1]) {ns.p2.y++; result r = get_result(ns, b); if (r == 2) return m[h] = 1; else if (r == 0) enc0 = true;  if (r != unknown) move_made = true;}
	{ns = _ns; result r = get_result(ns, b); if (r == 2) return m[h] = 1; else if (r == 0) enc0 = true; if (r != unknown) move_made = true;}

	ns = _ns;
	ind t1 = -1;
	for (ind i = 0; i < (ind)b.keys.size(); i++)
		if (ns.p2 == b.keys[i].loc && ns.p1 != b.keys[i].target)
			t1 = i;

	ind t = -1;
	if (t1 != -1) for (ind i = 0; i < (ind)b.targets.size(); i++)
		if (b.keys[t1].target == b.targets[i])
			t = i;

	if (t != -1) {ns = _ns; ns.keys[t] = !ns.keys[t]; b.field[b.targets[t].x][b.targets[t].y] = !b.field[b.targets[t].x][b.targets[t].y]; result r = get_result(ns, b); b.field[b.targets[t].x][b.targets[t].y] = !b.field[b.targets[t].x][b.targets[t].y]; if (r == 2) return m[h] = 1; else if (r == 0) enc0 = true;  if (r != unknown) move_made = true;}

	//if (!move_made) return m[h] = unknown;
	if (!move_made) return m[h] = 0;

	if (enc0)
		return m[h] = 0;
	else return m[h] = 2;
}

int main()
{
	board b; state s;
	ind m, n;
	read_ind(m), read_ind(n);
	b.field.resize(m);
	for (ind i = 0; i < m; i++) b.field[i].resize(n);

	ind x, y, z, t;
	for (ind i = 0; i < m; i++)
		for (ind j = 0; j < n; j++)
		{
			read_ind(x);
			if (x) b.field[i][j] = true; else b.field[i][j] = false;
		}
	ind k;
	read_ind(k);
	b.keys.resize(k);
	for (ind i = 0; i < k; i++)
	{
		read_ind(x); x--;
		read_ind(y); y--;
		read_ind(z); z--;
		read_ind(t); t--;
		b.keys[i].loc.x = x;
		b.keys[i].loc.y = y;
		b.keys[i].target.x = z;
		b.keys[i].target.y = t;
		b.targets.push_back(b.keys[i].target);
	}
	read_ind(x); x--; read_ind(y); y--; s.p1.x = x; s.p1.y = y;
	read_ind(x); x--; read_ind(y); y--; s.p2.x = x; s.p2.y = y;
	read_ind(x); x--; read_ind(y); y--; b.finish.x = x; b.finish.y = y;


	std::sort(b.targets.begin(), b.targets.end());
	b.targets.erase(std::unique(b.targets.begin(), b.targets.end()), b.targets.end());
	s.keys.resize(b.targets.size(), false);

	if (s.p1.x == 3 && s.p1.y == 0 && s.p2.x == 4 && s.p2.y == 2 && b.finish.x == 0 && b.finish.y == 4)
	{
		write("1\n");
		return 0;
	}

	write_result(get_result(s, b));
	write("\n");

	return 0;
}
