import static ru.ifmo.testlib.Outcome.quit;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;

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 {

	int gcd(int a, int b) {
		if (b == 0)
			return a;
		return gcd(b, a % b);
	}

	class Frac implements Comparable<Frac> {
		private BigInteger a, b;

		public Frac(int a, int b) {
			int d = gcd(a, b);
			this.a = BigInteger.valueOf(a / d);
			this.b = BigInteger.valueOf(b / d);
		}

		public Frac(BigInteger a, BigInteger b) {
			BigInteger d = a.gcd(b);
			this.a = a.divide(d);
			this.b = b.divide(d);
		}

		Frac add(Frac f) {
			return new Frac(a.multiply(f.b).add(f.a.multiply(b)), b
					.multiply(f.b));
		}

		Frac substract(Frac f) {
			return new Frac(a.multiply(f.b).subtract(f.a.multiply(b)), b
					.multiply(f.b));
		}

		@Override
		public String toString() {
			return a + "/" + b;
		}

		@Override
		public boolean equals(Object obj) {
			Frac f = (Frac) obj;
			return a.equals(f.a) && b.equals(f.b);
		}

		@Override
		public int compareTo(Frac that) {
			return a.multiply(that.b).compareTo(b.multiply(that.a));
		}
	}

	Frac readFrac(InStream is) {
		return parseFrac(is.nextToken());
	}

	Frac parseFrac(String s) {
		StringTokenizer st = new StringTokenizer(s, "/", true);
		try {
			int a = Integer.parseInt(st.nextToken());
			if (a < 0 || a > 1e9) {
				quit(Type.PE, s + " number out of range");
			}
			String ss = st.nextToken();
			if (!ss.equals("/")) {
				quit(Type.PE, "\"/\" expected");
			}
			int b = Integer.parseInt(st.nextToken());
			if (b <= 0 || b > 1e9) {
				quit(Type.PE, s + " number out of range");
			}
			if (gcd(a, b) != 1) {
				quit(Type.PE, "reducible fraction %d/%d", a, b);
			}
			if (st.hasMoreTokens()) {
				quit(Type.PE, "extra tokens in frac");
			}
			return new Frac(a, b);
		} catch (NumberFormatException nfe) {
			quit(Type.PE, nfe.toString());
		} catch (NoSuchElementException nsee) {
			quit(Type.PE, "bad frac: " + s);
		}
		return null;
	}

	@Override
	public Outcome test(InStream inf, InStream ouf, InStream ans) {
		int n = inf.nextInt();
		int m = inf.nextInt();
		int k = inf.nextInt();
		Frac timeJ = readFrac(ans);
		Frac timeP = readFrac(ouf);
		if (!timeJ.equals(timeP)) {
			quit(Type.WA, " wrong time expected %s found %s", timeJ, timeP);
		}
		int cnt = ouf.nextInt();
		if (!ouf.seekEoLn()) {
			quit(Type.PE, "Line 2: end of line expected");
		}
		if (cnt <= 0) {
			quit(Type.WA, " number of operations %d - not positive", cnt);
		}
		if (cnt > 10000) {
			quit(Type.WA, " number of operations %d - more than 10000", cnt);
		}
		Frac[] totalTime = new Frac[n];
		Arrays.fill(totalTime, new Frac(0, 1));
		int[] currentTester = new int[n];
		Arrays.fill(currentTester, -1);
		Frac[] startTime = new Frac[m];
		int[] currentComputer = new int[m];
		Arrays.fill(currentComputer, -1);
		for (int i = 0; i < cnt; i++) {
			String s = ouf.nextToken();
			StringTokenizer st = new StringTokenizer(s, ":", true);
			Frac time = parseFrac(st.nextToken());
			if (!st.hasMoreTokens()) {
				quit(Type.PE, ": expected");
			}
			String ss = st.nextToken();
			if (!ss.equals(":")) {
				quit(Type.PE, "Line %d: \"%s\" expected, \"%s\" found", i + 3,
						":", ss);
			}
			if (st.hasMoreTokens()) {
				quit(Type.PE, "Line %d: o_O", i + 3);
			}

			if (!ouf.nextToken().equals("Connect")) {
				quit(Type.PE, "Line %d: \"Connect\" expected", i + 3);
			}
			int Di = ouf.nextInt();
			if (Di < 1 || Di > m) {
				quit(Type.WA, "Line %d: Di = %d, out of range [1..%d]", i + 3,
						Di, m);
			}
			if (!ouf.nextToken().equals("to")) {
				quit(Type.PE, "Line %d: \"to\" expected", i + 3);
			}
			int Ki = Integer.parseInt(ouf.nextToken());
			if (Ki < 1 || Ki > n) {
				quit(Type.WA, "Line %d: Ki = %d, out of range [1..%d]", i + 3,
						Di, n);
			}
			Di--;
			Ki--;
			if (currentComputer[Di] != -1) {
				totalTime[currentComputer[Di]] = totalTime[currentComputer[Di]]
						.add(time).substract(startTime[Di]);
				currentTester[currentComputer[Di]] = -1;
				startTime[Di] = null;
				currentComputer[Di] = -1;
			}
			if (currentTester[Ki] != -1) {
				totalTime[Ki] = totalTime[Ki].add(time).substract(
						startTime[currentTester[Ki]]);
				startTime[currentTester[Ki]] = null;
				currentComputer[currentTester[Ki]] = -1;
				currentTester[Ki] = -1;
			}
			currentComputer[Di] = Ki;
			currentTester[Ki] = Di;
			startTime[Di] = time;
		}
		for (int i = 0; i < startTime.length; i++) {
			if (currentComputer[i] != -1) {
				totalTime[currentComputer[i]] = totalTime[currentComputer[i]]
						.add(timeP).substract(startTime[i]);
				currentTester[currentComputer[i]] = -1;
				startTime[i] = null;
				currentComputer[i] = -1;
			}
		}
		for (int i = 0; i < totalTime.length; i++) {
			if (totalTime[i].compareTo(new Frac(k, 1)) < 0) {
				quit(Type.WA,
						"Computer %d was tested only %s seconds, but need %d",
						i + 1, totalTime[i], k);
			}
		}
		quit(Type.OK, ":)");
		return null;
	}
}
