#include <algorithm>
#include <vector>
#include <numeric>
#include <functional>

#include "testlib.h"

using namespace std;

int n;
vector<int> x(4);

vector<pair<int, int>> e;

bool readAns(InStream& stream) {
	vector<int> part(n);
	for (int i = 0; i < n; ++i)
		part[i] = stream.readInt(0, 3);
	int cnt0 = count(part.begin(), part.end(), 0);
	if (cnt0) {
		if (cnt0 == n)
			return false;
		stream.quitf(_wa, "answer contains both zero and positive values");
	}
	vector<int> conn(4);
	for (int i = 0; i < n; ++i)
		++conn[part[i]];
	if (conn != x)
		stream.quitf(_wa, "invalid split: #1=%d, #2=%d, #3=%d", conn[1], conn[2], conn[3]);
	vector<int> f(n
	);
	iota(f.begin(), f.end(), 0);
	function<int(int)> find = [&](int x) { return f[x] == x ? x : f[x] = find(f[x]); };
	for (const auto& ed : e) {
		int u = ed.first, v = ed.second;
		if (part[u] == part[v]) {
			u = find(u); v = find(v);
			if (u != v) {
				f[u] = v;
				--conn[part[u]];
			}
		}
	}
	int hm = count(conn.begin(), conn.end(), 1);
	if (hm < 2)
		stream.quitf(_wa, "%d components are not connected", 3 - hm);
	return true;
}

int main(int argc, char* argv[]) {
	registerTestlibCmd(argc, argv);
	
	n = inf.readInt(1, 100000);
	inf.readSpace();
	int m = inf.readInt(1, 200000);
	inf.readEoln();
	x[1] = inf.readInt(1, n); inf.readSpace();
	x[2] = inf.readInt(1, n); inf.readSpace();
	x[3] = inf.readInt(1, n); inf.readEoln();
	e.resize(m);
	for (int i = 0; i < m; ++i) {
		e[i].first = inf.readInt(0, n - 1); inf.readSpace();
		e[i].second = inf.readInt(0, n - 1); inf.readEoln();
	}
	inf.readEof();

	bool pa = readAns(ouf), ja = readAns(ans);
	if (pa == ja)
		if (pa)
			quit(_ok, "OK, answer exists");
		else
			quit(_ok, "OK, no solution");
	if (ja)
		quit(_wa, "participant didn't find answer, but answer exists");
	else
		quit(_fail, "answer exists, but jury didn't find");

	return 0;
}
