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 <iostream>
#include <vector>
#include <algorithm>

using namespace std;

struct P{
	double x;
	double y;
};

int ccw(P p0, P p1, P p2)
{
	double dx1 = p1.x-p0.x;
	double dy1 = p1.y-p0.y;
	double dx2 = p2.x-p0.x;
	double dy2 = p2.y-p0.y;
	
	if(dx1*dy2 > dy1*dx2){
		return 1;
	} 
	if(dx1*dy2 < dy1*dx2){
		return -1;
	}
	if((dx1*dx2 < 0) || (dy1*dy2 < 0)){
		return -1;
	}
	if((dx1*dx1+dy1*dy1)<(dx2*dx2+dy2*dy2)){
		return 1;
	}
	
	return 0;
}

namespace std {
  bool operator < (const P& a, const P& b) {
    return a.x != b.x ? a.x < b.x : a.y < b.y;
  }
}

vector<P> convex_hull(vector<P> vec)
{
	int n = vec.size(), k = 0;
	sort(vec.begin(), vec.end());
	vector<P> ch(2*n);
	
	for(int i = 0; i < n; ch[k++] = vec[i++]){
		while(k >= 2 && ccw(ch[k-2], ch[k-1], vec[i]) <= 0){
			k--;
		}
	}
	
	for(int i = n-2, t = k+1; i >= 0; ch[k++] = vec[i--]){
		while(k >= t && ccw(ch[k-2], ch[k-1], vec[i]) <= 0){
			k--;
		}
	}
	
	ch.resize(k-1);
	
	return ch;
}

bool check(vector<P> vec, P p)
{
	bool f = false;
	
	for(int i = 0; i < vec.size(); i++){
		if(p.x == vec[i].x && p.y == vec[i].y){
			f = true;
			break;
		}
	}
	
	return f;
}


int main()
{
	int n;
	bool f;
	P pr[3], s, t;
	
	while(cin>>n && n){
		while(n--){
			cin >> pr[0].x >> pr[0].y >> pr[1].x >> pr[1].y >> pr[2].x >> pr[2].y >> s.x >> s.y >> t.x >> t.y;
			f = true;
			vector<P> vec;
			for(int i = 0; i < 3; i++){
				vec.push_back(pr[i]);
			}
			vec.push_back(t);
			vec = convex_hull(vec);
			if(vec.size() == 4){
				cout << "NG" << endl;
				continue;
			}
			if(check(vec, t)){
				cout << "NG" << endl;
				continue;
			}
			vec.clear();
			for(int i = 0; i < 3; i++){
				vec.push_back(pr[i]);
			}
			vec.push_back(s);
			vec = convex_hull(vec);
			if(vec.size() == 4){
				cout << "OK" << endl;
			} else {
				if(check(vec, s)){
					cout << "OK" << endl;
				} else {
					cout << "NG" << endl;
				}
			}
		}
	}
	
	return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;

typedef complex<double> P;

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

bool isIn(P p, P a, P b, P c) {
  if(cross(b-a, p-a) < 0) return false;
  if(cross(c-b, p-b) < 0) return false;
  if(cross(a-c, p-c) < 0) return false;
  return true;
}

int main() {
  int Tc;
  cin >> Tc;
  while(Tc--) {
    P a, b, c, d, e;
    cin >> a.real() >> a.imag() >> b.real() >> b.imag()
        >> c.real() >> c.imag() >> d.real() >> d.imag()
        >> e.real() >> e.imag();
    if(cross(b-a, c-a) < 0) swap(b,c);
    bool A = isIn(d,a,b,c);
    bool B = isIn(e,a,b,c);
    if(A ^ B) cout << "OK" << endl;
    else cout << "NG" << endl;
  }
  return 0;
}