Problem:
牽牛と織女

織女は天帝の子供でしたが、父の言いつけであけてもくれても機を織っていました。

織女の織る雲錦という見事な布で仕立てた服を着るのが天帝の楽しみでした。雲錦は寿命が短くすぐに劣化してしまいますが、働き者の織女が毎日織ってくれるので、問題はありませんでした。織女は、父の言いつけを守り、毎日毎日雲錦を織り続けていたので、ボーイフレンドはいませんでした。かわいそうに思った父は、天の川の向こう岸に住む牽牛という働き者を紹介し、嫁入りさせました。

すると、織女は、結婚の楽しさに夢中になって、機織りなどそっちのけで、牽牛と遊び呆けています。天帝のお気に入りの雲錦の服も新しく仕立てられないためボロボロになってしまいました。

これには父も怒って、織女を宮殿に連れ戻したいと思いました。しかし人間である牽牛の前にボロボロの服で姿を現すわけにはいきません。遊び呆けている二人を 3 角形の壁で遮断し自分以外の全てのものが行き来できなくすることを考えました。そして、牽牛に見つからずに、織女に会って、まじめに機を織るか、さもなければ強制的に連れ帰ると宣言するというのです。

天帝はこの作戦を遂行するために 3 角形の壁生成装置を開発することにしました。3 角形の 3 頂点の位置 (xp1, yp1), (xp2, yp2), (xp3, yp3)、牽牛の位置 (xk, yk)、および織女の位置 (xs, ys)、を入力とし、三角形が牽牛と織女を遮断しているか否かを判定し、遮断できている場合は OK、遮断できていない場合には NG を出力するプログラムを作成してください。ただし、遮断しているとは、牽牛と織女のいずれかが三角形の内側にあり、他方が外側にある場合を言います。牽牛と織女は三角形の頂点もしくは辺の上にはいないものとします。

織女と牽牛は時々刻々場所を変えるため、プログラムは様々な位置情報を入力し質問に答えなければなりません。

Input

入力は以下の形式で与えられます。

n
query1
query2
:
queryn

１行目に判別したい情報の個数 n (n ≤ 10000)、続く n 行に i 番目の質問 queryi が与えられます。各質問は以下の形式で与えられます。

xp1 yp1 xp2 yp2 xp3 yp3 xk yk xs ys

各質問として、3 角形の 3 頂点の位置、牽牛の位置、および織女の位置 (-1000 ≤ xp1, yp1, xp2, yp2, xp3, yp3, xk, yk, xs, ys ≤ 1000) が１行に与えられます。入力はすべて整数です。

Output

質問ごとに、判定結果 OK または NG を１行に出力してください。

Sample Input

5
2 5 9 2 8 9 2 11 6 5
2 5 9 2 8 9 2 11 12 6
2 5 9 2 8 9 2 11 11 9
14 1 25 7 17 12 17 9 20 5
14 1 25 7 17 12 22 13 20 5

Output for the Sample Input

OK
NG
NG
NG
OK

Solution in JAVA (judge verdict: Accepted)

import static java.lang.Math.*;
import static java.util.Arrays.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class Main {

	static void tr(Object... os) {
		System.err.println(deepToString(os));
	}

	static class P implements Comparable<P> {
		double x, y;
		public P(double x, double y) {
			this.x = x;
			this.y = y;
		}
		public int compareTo(P o) {
			return x != o.x ? Double.compare(x, o.x) : Double.compare(y, o.y);
		}
		public String toString() {
			return "(" + x + "," + y + ")";
		}
		public double abs() {return sqrt(x * x + y * y); }
		public double abs2() {return (x * x + y * y); }
		public double arg() { return atan2(y, x); } // (-pi 〜 pi)
		public double dist(P o) {return this.sub(o).abs(); }
		public P mul(double k) {return new P(x * k, y * k);}
		public P div(double k) {return new P(x / k, y / k);}
		public P add(P o) {return new P(x + o.x, y + o.y);}
		public P sub(P o) {return new P(x - o.x, y - o.y);}
		public P mul(P o) {return new P(x * o.x - y * o.y,  x * o.y + y * o.x); }
		public P div(P o) {return new P(x * o.x + y * o.y, -x * o.y + y * o.x).div(o.abs2()); }
		public double dot(P o) {return x * o.x + y * o.y;} // a b sin(t)
		public double det(P o) {return x * o.y - y * o.x;} // a b cos(t)
		public P normal() { return this.div(this.abs()); }
		public P rot90() { return new P(-y, x); }
		public static P polar(double d, double rad) {return new P(d * Math.cos(rad), d * Math.sin(rad));}
	}

	int signum(double x) {
		if (x < 0) return -1;
		if (x > 0) return +1;
		return 0;
	}
	final int OUT = 0;
	final int IN = 1;
	final int ON = 2;
	int containTP(P a, P b, P c, P p) {
		b = b.sub(a); c = c.sub(a); p = p.sub(a);
		double det = b.det(c);
		int sd = signum(det);
		if (sd == 0) return OUT;
		double s = p.det(c);
		double t = b.det(p);
		if (sd == -1) {det = -det; s = -s; t = -t;}
		return (0 <= s && s <= det && 0 <= t && t <= det && s + t <= det) ? IN : OUT;
	}

	void solve() {
		P[] ps = new P[3];
		for (int i = 0; i < 3; i++) {
			ps[i] = new P(sc.nextDouble(), sc.nextDouble());
		}
		P s = new P(sc.nextDouble(), sc.nextDouble());
		P t = new P(sc.nextDouble(), sc.nextDouble());

		int r1 = containTP(ps[0], ps[1], ps[2], s);
		int r2 = containTP(ps[0], ps[1], ps[2], t);
		out.println(r1 != r2 ? "OK":"NG");
	}

	public static void main(String[] args) throws Exception {
		new Main().run();
	}

	MyScanner sc = null;
	PrintWriter out = null;
	public void run() throws Exception {
		sc = new MyScanner(System.in);
		out = new PrintWriter(System.out);
		sc.nextInt();
		for (;sc.hasNext();) {
			solve();
			out.flush();
		}
		out.close();
	}

	class MyScanner {
		String line;
		BufferedReader reader;
		StringTokenizer tokenizer;

		public MyScanner(InputStream stream) {
			reader = new BufferedReader(new InputStreamReader(stream));
			tokenizer = null;
		}
		public void eat() {
			while (tokenizer == null || !tokenizer.hasMoreTokens()) {
				try {
					line = reader.readLine();
					if (line == null) {
						tokenizer = null;
						return;
					}
					tokenizer = new StringTokenizer(line);
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
		}
		public String next() {
			eat();
			return tokenizer.nextToken();
		}
		public String nextLine() {
			try {
				return reader.readLine();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		public boolean hasNext() {
			eat();
			return (tokenizer != null && tokenizer.hasMoreElements());
		}
		public int nextInt() {
			return Integer.parseInt(next());
		}
		public long nextLong() {
			return Long.parseLong(next());
		}
		public double nextDouble() {
			return Double.parseDouble(next());
		}
		public int[] nextIntArray(int n) {
			int[] a = new int[n];
			for (int i = 0; i < n; i++) a[i] = nextInt();
			return a;
		}
	}
}