Go: package main

import (
	"bufio"
	"os"
	"strconv"
	"strings"
	"fmt"
)

var scanner = bufio.NewScanner(os.Stdin)

func main() {
	scanner.Scan()
	n, _ := strconv.Atoi(scanner.Text())
	for i := 0; i < n; i++ {
		scanner.Scan()
		input := strings.Split(scanner.Text(), " ")
		buf := make([]float64, len(input))
		for j := range buf {
			buf[j], _ = strconv.ParseFloat(input[j], 64)
		}
		p1 := complex(buf[0], buf[1])
		p2 := complex(buf[2], buf[3])
		p3 := complex(buf[4], buf[5])
		pk := complex(buf[6], buf[7])
		ps := complex(buf[8], buf[9])
		kin := isAtSameSide(p3, pk, []complex128{p1, p2}) &&
			isAtSameSide(p1, pk, []complex128{p2, p3}) &&
			isAtSameSide(p2, pk, []complex128{p3, p1})
		sin := isAtSameSide(p3, ps, []complex128{p1, p2}) &&
			isAtSameSide(p1, ps, []complex128{p2, p3}) &&
			isAtSameSide(p2, ps, []complex128{p3, p1})
		if (kin || sin) && !(kin && sin) {
			fmt.Println("OK")
		} else {
			fmt.Println("NG")
		}
	}
}

func isAtSameSide(a, b complex128, line []complex128) bool {
	sa := (real(line[1]) - real(line[0]))*(imag(a)-imag(line[0]))+
		(imag(line[1])-imag(line[0]))*(real(line[0])-real(a))
	sb := (real(line[1]) - real(line[0]))*(imag(b)-imag(line[0]))+
		(imag(line[1])-imag(line[0]))*(real(line[0])-real(b))
	return (sa > 0 && sb > 0) || (sa < 0 && sb < 0)
}

C++: #include <bits/stdc++.h>

using namespace std;

#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,n) FOR(i,0,n)

#define EPS (1e-8)
#define EQ(a,b) (abs((a)-(b)) < EPS)
#define EQV(a,b) ( EQ(a.real(), b.real()) && EQ(a.imag(), b.imag()) )

typedef complex<double> p;

double cross(p a, p b) {
	return (a.real() * b.imag() - a.imag() * b.real());
}

int main() {
	int n;
	cin >> n;
	while (n--) {
		p point[5];
		REP(i, 5) {
			double a, b;
			scanf("%lf %lf", &a, &b);
			point[i] = p(a, b);
		}
		int cnt[2] = {};
		
		REP(i, 3) {
			p v[2];
			v[0] = point[(i + 1) % 3] - point[i];
			v[1] = point[3] - point[i];
			if (cross(v[0], v[1]) < -EPS) cnt[0]++;
			
			v[1] = point[4] - point[i];
			if (cross(v[0], v[1]) < -EPS) cnt[1]++;
		}
		bool flag[2];
		REP(i, 2) flag[i] = cnt[i] == 0 || cnt[i] == 3;
		if (flag[0] == !flag[1]) puts("OK");
		else puts("NG");
	}
	return 0;
}

C++: #include <iostream>

using namespace std;

class Point{
public:
	int x;
	int y;

	Point(int x = 0, int y = 0){
		this->x = x;
		this->y = y;
	}

	int dot(Point other){
		int d =  (*this).x*other.x + (*this).y*other.y;
		return (*this).x*other.x + (*this).y*other.y;
	}

	int cross(Point other){
		return (*this).x*other.y - (*this).y*other.x;
	}

	int distsq(Point other){
		//int dx = (*this).x-other.x;
		//int dy = (*this).y-other.y;
		return ((*this).x-other.x)*((*this).x-other.x)+((*this).y-other.y)*((*this).y-other.y);
	}

	Point operator+(Point other){
		Point p;
		p.x = (*this).x + other.x;
		p.y = (*this).y + other.y;
		return p;
	}

	Point operator+=(Point other){
		(*this) = (*this)+other;
		return (*this);
	}

	Point operator-(Point other){
		Point p;
		p.x = (*this).x - other.x;
		p.y = (*this).y - other.y;
		return p;
	}

	Point operator-=(Point other){
		(*this) = (*this)-other;
		return (*this);
	}

	// cout 出力用
   friend ostream& operator << (ostream& os, const Point& p){
	   os << '(' << p.x << ", " << p.y << ')';
	   return os;
   }

};

class Triangle{
public:
	Point vertex[3];

	Triangle(Point a = Point(0,0), Point b = Point(0,0), Point c = Point(0,0)){
		vertex[0] = a;
		vertex[1] = b;
		vertex[2] = c;
	}

	bool isInclude(Point p){
		// 三角形ABCと点Pに関し、3つの外積 AB×AP, BC×BP, CA×CPの符号が同じであれば三角形の中
		int cnt = 0;
		for(int i = 0; i < 3; i++){
			Point vs = vertex[(i+1)%3] - vertex[i]; // 辺のベクトル
			Point vp = p - vertex[i];				// 各辺の始点→点Pのベクトル
			cnt += (vs.cross(vp) > 0)?1:-1;
		}
		cnt = (cnt>0)?cnt:-cnt;
		if(cnt == 3) return true;
		else return false;
	}
};

int main(){
	int n;
	cin >> n;

	while(n--){
		Triangle wall;
		Point a, b;
		for(int i = 0; i < 3; i++){
			cin >> wall.vertex[i].x >> wall.vertex[i].y;
		}
		cin >> a.x >> a.y >> b.x >> b.y;

		if(wall.isInclude(a)^wall.isInclude(b)) cout << "OK" << endl;
		else cout << "NG" << endl;
	}

	return 0;

}

C++: #include <complex>
#include <cmath>
#include <cstdio>
 
using namespace std;
 
typedef double D;
typedef complex<D> P;
#define EPS (1e-10)


D dot(P a,P b){
  return real(conj(a) * b);
}

D cross(P a,P b){
  return imag(conj(a) * b);
} 

int ccw(P p0,P p1,P p2){
  P a = p1 - p0;
  P b = p2 - p0;
 
  if(cross(a,b) > EPS) return 1;
  if(cross(a,b) < -EPS) return -1;
  if(dot(a,b) < -EPS) return 2;
  if(norm(a) < norm(b)) return -2;
  return 0;
}

bool check(P p1,P p2,P p3,P p4){
  return (ccw(p1,p2,p3)*ccw(p1,p2,p4) <= 0 &&
      ccw(p3,p4,p1)*ccw(p3,p4,p2) <= 0);
}
 
int main(){
  int n;
  P P[3],T[2];
 
  scanf("%d" ,&n);
  while(n--){
    for(int i = 0 ; i < 3 ; i++){
      scanf("%lf %lf" ,&P[i].real() ,&P[i].imag());
    }

    for(int i = 0 ; i < 2 ; i++){
      scanf("%lf %lf" ,&T[i].real() ,&T[i].imag());
    }

    int cnt = 0; 
    if(check(P[0],P[1],T[0],T[1])){
      cnt++;
    }   
    if(check(P[0],P[2],T[0],T[1])){
      cnt++;
    } 
    if(check(P[1],P[2],T[0],T[1])){
      cnt++;
    } 
 
    if(cnt % 2){
      puts("OK");
    }else{
      puts("NG");
    }
  }
 
  return 0;
}

C++: #define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES

#include <stdio.h>
#include <ctype.h>
#include <string>
#include <iostream>
#include <vector>
#include <stack>
#include <fstream>
#include <sstream>
#include <queue>
#include <exception>
#include <cmath>
#include <numeric>
#include <map>
#include <algorithm>
#include <bitset>
#include <set>
#include <functional>

#define FOR(i,a,b) for (int i=(a);i<(b);i++)
#define RFOR(i,a,b) for (int i=(b)-1;i>=(a);i--)
#define REP(i,n) for (int i=0;i<(n);i++)
#define RREP(i,n) for (int i=(n)-1;i>=0;i--)

using namespace std;
typedef long long int lint;

class Point {
public:
	int x;
	int y;

	Point() {
		x = y = 0;
	}
	Point(int x, int y) {
		this->x = x; this->y = y;
	}

	Point operator + (Point obj) {
		return Point(this->x + obj.x, this->y + obj.y);
	}
	Point operator - (Point obj) {
		return Point(this->x - obj.x, this->y - obj.y);
	}
	int operator * (Point obj) {
		return (this->x * obj.y - this->y * obj.x);
	}

	friend std::ostream& operator << (std::ostream& ostr, const Point& p) {
		std::cout << "{" << p.x << ", " << p.y << "}";
		return ostr;
	}
};

bool interior(Point p1, Point p2, Point p3, Point p) {
	Point v1, v2, v3, pp1, pp2, pp3;
	v1 = p2 - p1; v2 = p3 - p2; v3 = p1 - p3;
	pp1 = p - p1; pp2 = p - p2; pp3 = p - p3;
	int cp1, cp2, cp3;
	cp1 = v1 * pp1; cp2 = v2 * pp2; cp3 = v3 * pp3;
	if (cp1 < 0 && cp2 < 0 && cp3 < 0) return true;
	if (cp1 > 0 && cp2 > 0 && cp3 > 0) return true;
	return false;
}

void AOJ0143()
{
	Point p[3], k, s;
	REP(i, 3) {
		cin >> p[i].x >> p[i].y;
	}
	cin >> k.x >> k.y >> s.x >> s.y;

	if (interior(p[0], p[1], p[2], k) ^ interior(p[0], p[1], p[2], s)) {
		cout << "OK" << endl;
	}
	else cout << "NG" << endl;

	return;
}

int main()
{
	int n;
	cin >> n;
	REP(i, n) AOJ0143();

	return 0;
}