import java.util.*;

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

public class Check implements ru.ifmo.testlib.Checker {

	@Override
	public Outcome test(InStream inf, InStream ouf, InStream ans) {
		int n = inf.nextInt();
		Point[] p = new Point[n];
		for (int i = 0; i < n; i++) {
			p[i] = new Point(inf.nextInt(), inf.nextInt());
		}
		String anss = ans.nextToken();
		String oufs = ouf.nextToken();
		if ("No".equals(oufs)) {
			String oufs2 = ouf.nextToken();
			if (!"solution".equals(oufs2)) {
				return new Outcome(Type.PE, "No soltuion expected, " + oufs + " " + oufs2 + " found");
			}
			if ("No".equals(anss)) {
				return new Outcome(Type.OK, "No soltuion");
			}
			return new Outcome(Type.WA, "Solution not found");
		}
		int[] perm = new int[n];
		try {
			perm[0] = Integer.parseInt(oufs);
		} catch (NumberFormatException e) {
			return new Outcome(Type.PE, "Number or No expected, " + oufs + " found");
		}
		for (int i = 1; i < n; i++) {
			perm[i] = ouf.nextInt();
		}
		boolean[] used = new boolean[n];
		for (int i : perm) {
			if (i < 1 || i > n) {
				return new Outcome(Type.WA, "Wrong hopper number: " + i);
			}
			if (used[i - 1]) {
				return new Outcome(Type.WA, "Duplicate hoppers found");
			}
			used[i - 1] = true;
		}
		
		Segment[] s = new Segment[n];
		for (int i = 0; i < n; i++) {
			s[i] = new Segment(p[perm[i] - 1], p[perm[(i + 1) % n] - 1], i);
		}
		Event[] events = new Event[2 * n];
		for (int i = 0; i < n; i++) {
			events[2 * i] = new Event(-1, s[i], s[i].p1);
			events[2 * i + 1] = new Event(1, s[i], s[i].p2);
		}
		Arrays.sort(events);
		
		TreeSet<Segment> ts = new TreeSet<Segment>();
		for (Event e : events) {
			position = e.p.x; 
			if (e.type == -1) {
				Segment up = ts.ceiling(e.s);
				if (up != null && e.s.inter(up)) {
					return new Outcome(Type.WA, "Segments intersect: " + e.s + " " + up);
				}
				Segment down = ts.floor(e.s);
				if (down != null && e.s.inter(down)) {
					return new Outcome(Type.WA, "Segments intersect: " + e.s + " " + down);
				}
				ts.add(e.s);
			} else {
				ts.remove(e.s);
				Segment up = ts.ceiling(e.s);
				if (up != null && e.s.inter(up)) {
					return new Outcome(Type.WA, "Segments intersect: " + e.s + " " + up);
				}
				Segment down = ts.floor(e.s);
				if (down != null && e.s.inter(down)) {
					return new Outcome(Type.WA, "Segments intersect: " + e.s + " " + down);
				}
				if (down != null && up != null && up.inter(down)) {
					return new Outcome(Type.WA, "Segments intersect: " + down + " " + up);
				}
			}
		}
		
		if ("No".equals(anss)) {
			return new Outcome(Type.FAIL, "Contestant found better solution");
		}
		return new Outcome(Type.OK, "Soltuion found");
	}
	
	static int position;
	
	class Point implements Comparable<Point> {
		int x, y;
		
		Point(int x, int y) {
			this.x = x;
			this.y = y;
		}

		@Override
		public int compareTo(Point o) {
			if (x != o.x) return x - o.x;
			return y - o.y;
		}
		
		@Override
		public String toString() {
			return x + " " + y;
		}
	}
	
	class Segment implements Comparable<Segment> {
		Point p1, p2;
		long a, b, c;
		int num;
		
		Segment(Point p1, Point p2, int n) {
			num = n;
			if (p2.compareTo(p1) > 0) {
				this.p1 = p1;
				this.p2 = p2;
			} else {
				this.p1 = p2;
				this.p2 = p1;
			}
			a = p2.y - p1.y;
			b = p1.x - p2.x;
			c = -a * p1.x - b * p1.y;
		}
		
		@Override
		public boolean equals(Object o) {
			if (!(o instanceof Segment)) return false;
			Segment s = (Segment) o;
			return p1.compareTo(s.p1) == 0 && p2.compareTo(s.p2) == 0;
		}
		
		int side(Point p) {
			return sign(a * p.x + b * p.y + c);
		}
		
		boolean inside(Point p) {
			if (side(p) != 0) return false;
			long sm1 = smul(p.x - p1.x, p.y - p1.y, p2.x - p1.x, p2.y - p1.y);
			long sm2 = smul(p.x - p2.x, p.y - p2.y, p1.x - p2.x, p1.y - p2.y);
			if (sm1 > 0 && sm2 > 0) return true;
			return false;
		}
		
		boolean inter(Segment s) {
			if (equals(s)) return true;
			int s1 = side(s.p1) * side(s.p2);
			int s2 = s.side(p1) * s.side(p2);
			if (s1 < 0 && s2 < 0) return true;
			if (inside(s.p1) || inside(s.p2)) return true;
			if (s.inside(p1) || s.inside(p2)) return true;
			return false;
		}
		
		double getY() {
			if (p1.x == p2.x) return p1.y;
			return 1.0 * (position - p1.x) * (p2.y - p1.y) / (p2.x - p1.x);
		}

		@Override
		public int compareTo(Segment o) {
			int t = Double.compare(getY(), o.getY());
			if (t == 0) {
				return num - o.num;
			}
			return t;
		}
		
		@Override
		public String toString() {
			return p1 + " " + p2;
		}
	}
	
	class Event implements Comparable<Event> {
		int type;
		Point p;
		Segment s;
		
		public Event(int i, Segment segment, Point p1) {
			type = i;
			s = segment;
			p = p1;
		}

		@Override
		public int compareTo(Event o) {
			if (p.x != o.p.x) {
				return p.x - o.p.x;
			}
			return type - o.type;
		}
	}
	
	static int sign(long l) {
		if (l < 0) return -1;
		if (l > 0) return 1;
		return 0;
	}
	
	static long smul(long x1, long y1, int x2, int y2) {
		return x1 * x2 + y1 * y2;
	}

	static boolean inBound(int x, int l, int r) {
		return l <= x && x <= r;
	}
}
