import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.TreeSet;

import ru.ifmo.testlib.Checker;
import ru.ifmo.testlib.InStream;
import ru.ifmo.testlib.Outcome;
import ru.ifmo.testlib.Outcome.Type;

public class Check implements Checker {

	@Override
	public Outcome test(InStream inf, InStream ouf, InStream ans) {
		int n = inf.nextInt(), m = inf.nextInt();
		int[] type = new int[n];
		for (int i = 0; i < n; i++) {
			type[i] = inf.nextInt();
		}

		int juryFirst = ans.nextInt(), partFirst = ouf.nextInt();
		if (partFirst == -1) {
			if (juryFirst == -1) {
				return new Outcome(Type.OK, "-1 = -1");
			} else {
				return new Outcome(Type.WA, "No way found, but it exists");
			}
		}

		int partFrom = partFirst - 1, partTo = ouf.nextInt() - 1;
		if (partFrom < 0 || partFrom >= n) {
			return new Outcome(Type.WA, "First number in output violates range [1, " + n + "] and is not -1");
		}
		if (partTo < 0 || partTo >= n) {
			return new Outcome(Type.WA, "Second number in output violates range [1, " + n + "]");
		}
		if (type[partFrom] != 1) {
			return new Outcome(Type.WA, "No first company in town " + (partFrom + 1));
		}
		if (type[partTo] != 2) {
			return new Outcome(Type.WA, "No second company in town " + (partTo + 1));
		}
		
		int partDist = ouf.nextInt();
		
		int realDistance = findDistance(n, m, inf, partFrom, partTo);
		if (realDistance == -1) {
			return new Outcome(Type.WA, "No path between " + (partFrom + 1) + " and " + (partTo + 1) + " exists");
		}
		if (realDistance != partDist) {
			return new Outcome(Type.WA, "Cost of shortest path from " + (partFrom + 1) + " to " + (partTo + 1) + " is not equal to " + partDist); 
		}
		
		if (juryFirst == -1) {
			return new Outcome(Type.FAIL, "Jury didn't find answer, but participant did");
		}
		
		int juryFrom = juryFirst - 1, juryTo = ans.nextInt() - 1;
		int juryDist = ans.nextInt();
		if (juryDist < partDist) {
			return new Outcome(Type.WA, "Participant's shortest distance is too long: expected " + juryDist + ", but found " + partDist);
		}
		if (partDist < juryDist) {
			return new Outcome(Type.FAIL, "Participant found better answer: expected " + juryDist + ", but found " + partDist);
		}

		return new Outcome(Type.OK, "Shortest path found");
	}

	public int findDistance(int n, int m, InStream inf, int start, int end) {
		List<Edge>[] graph = new List[n];
		for (int i = 0; i < n; i++) {
			graph[i] = new ArrayList<>();
		}

		for (int i = 0; i < m; i++) {
			int from = inf.nextInt() - 1, to = inf.nextInt() - 1, length = inf
					.nextInt();
			graph[from].add(new Edge(to, length));
			graph[to].add(new Edge(from, length));
		}

		final int INF = Integer.MAX_VALUE / 2;
		TreeSet<Vertex> set = new TreeSet<>();
		int[] distance = new int[n];
		Arrays.fill(distance, INF);
		distance[start] = 0;
		set.add(new Vertex(start, distance[start]));
		
		while (!set.isEmpty()) {
			Vertex min = set.pollFirst();
			if (min.distance == INF) {
				break;
			}
			if (min.id == end) {
				return min.distance;
			}

			for (Edge edge : graph[min.id]) {
				int endPoint = edge.endPoint;
				Vertex vertex = new Vertex(endPoint, distance[endPoint]);

				if (distance[endPoint] > min.distance + edge.length) {
					set.remove(vertex);

					distance[endPoint] = min.distance + edge.length;
					vertex.distance = distance[endPoint];

					set.add(vertex);
				}
			}
		}
		
		return -1;
	}

	class Edge {
		int endPoint, length;

		public Edge(int endPoint, int length) {
			this.endPoint = endPoint;
			this.length = length;
		}
	}

	class Vertex implements Comparable<Vertex> {
		int distance, id;

		public Vertex(int id, int distance) {
			this.id = id;
			this.distance = distance;
		}

		@Override
		public int compareTo(Vertex o) {
			int cmp = Integer.compare(distance, o.distance);
			if (cmp != 0) {
				return cmp;
			}
			return Integer.compare(id, o.id);
		}
	}

}
