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 <queue>
#include <vector>
#include <iostream>
#include <vector>
#include <string>
#include <cassert>
#include <algorithm>
#include <functional>
#include <cmath>
#include <queue>
#include <set>
#include <stack>
#include <deque>
#include <map>
#include <iomanip>
#include <utility>
#include <stack>
using ll = long long;
using ld = long double;
using namespace std;
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
#define all(x) (x).begin(),(x).end()
#define rep3(var, min, max) for (ll (var) = (min); (var) < (max); ++(var))
#define repi3(var, min, max) for (ll (var) = (max) - 1; (var) + 1 > (min); --(var))
#define Mp(a,b) make_pair((a),(b))
#define F first
#define S second
#define Icin(s) ll (s);cin>>(s);
#define Scin(s) ll (s);cin>>(s);
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }
const double EPS=1e-10;
double add(double l, double r){
    if(abs(l+r)<EPS*(abs(l)+abs(r))) return 0;
    return l+r;
}
//l-r は add(l,-r)
//l==r は add(l,-r)==0
struct Pt{
    double x, y;
    Pt(double xx=0, double yy=0){x=xx; y=yy;}
    Pt& operator=(const Pt &rhs){
        x=rhs.x; y=rhs.y; return *this;
    }
    Pt& operator+=(const Pt &rhs){
        x = add(x,rhs.x); y = add(y,rhs.y); return *this;
    }
    Pt& operator-=(const Pt &rhs){
        x = add(x,-rhs.x); y = add(y,-rhs.y); return *this;
    }
    Pt& operator*=(const double &rhs){
        x *= rhs; y *= rhs; return *this;
    }
    Pt& operator/=(const double &rhs){
        x /= rhs; y /= rhs; return *this;
    }
};
Pt operator+(const Pt &a){return a;}
Pt operator-(const Pt &a){return Pt(-a.x,-a.y);}
Pt operator+(const Pt &lhs, const Pt &rhs){
    Pt ans=lhs; ans += rhs; return ans;
}
Pt operator-(const Pt &lhs, const Pt &rhs){
    Pt ans=lhs; ans -= rhs; return ans;
}
Pt operator*(const Pt &lhs, const double &rhs){
    Pt ans=lhs; ans *= rhs; return ans;
}
Pt operator*(const double &lhs, const Pt &rhs){
    Pt ans=rhs; ans *= lhs; return ans;
}
Pt operator/(const Pt &lhs, const double &rhs){
    Pt ans=lhs; ans /= rhs; return ans;
}
bool operator==(const Pt &lhs, const Pt &rhs){
    return add(lhs.x,-rhs.x)==0 && add(lhs.y,-rhs.y)==0;
}
bool operator!=(const Pt &lhs, const Pt &rhs){return !(lhs==rhs);}
bool operator<(const Pt &lhs, const Pt &rhs){
    return add(lhs.x,-rhs.x)!=0 ? lhs.x<rhs.x : add(lhs.y,-rhs.y)<0;
}
bool operator>(const Pt &lhs, const Pt &rhs){return rhs<lhs;}
bool operator<=(const Pt &lhs, const Pt &rhs){return !(lhs>rhs);}
bool operator>=(const Pt &lhs, const Pt &rhs){return !(lhs<rhs);}
istream& operator>>(istream &is, Pt &rhs){
    double x, y;
    is >> x >> y;
    rhs=Pt(x,y);
    return is;
}
ostream& operator<<(ostream &os, const Pt &rhs){
    os << rhs.x << " " << rhs.y;
    return os;
}
double norm(const Pt &a){return add(a.x*a.x,a.y*a.y);}
double abs(const Pt &a){return sqrt(norm(a));}
double dot(Pt a, Pt b){return add(a.x*b.x,a.y*b.y);}
double cross(Pt a, Pt b){return add(a.x*b.y,-a.y*b.x);}
int ccw(Pt a, Pt b, Pt c) {
    b -= a; c -= a;
    if(cross(b, c)>0) return +2;  // counter clockwise
    if(cross(b, c)<0) return -2;  // clockwise
    if(dot(b, c)<0) return +1;        // c--a--b on line
    if(norm(c)<norm(b)) return -1;    // b--c--a on line
    return 0;                         // a--b--c on line
}
bool judge_cross(ld ax,ld ay,ld bx,ld by,ld cx,ld cy,ld dx,ld dy){
    ld ta = (cx - dx) * (ay - cy) + (cy - dy) * (cx - ax);
    ld tb = (cx - dx) * (by - cy) + (cy - dy) * (cx - bx);
    ld tc = (ax - bx) * (cy - ay) + (ay - by) * (ax - cx);
    ld td = (ax - bx) * (dy - ay) + (ay - by) * (ax - dx);

  return tc * td < 0 && ta * tb < 0;
}
int main(){
    int n;
    cin>>n;
    rep(i,n){
        vector<Pt> vec(3);
        rep(j,3)cin>>vec[j];
        ld xk,yk,xs,ys;
        cin>>xk>>yk>>xs>>ys;
        int c=0;
        if(judge_cross(vec[0].x,vec[0].y,vec[1].x,vec[1].y,xk,yk,xs,ys))c++;
        if(judge_cross(vec[1].x,vec[1].y,vec[2].x,vec[2].y,xk,yk,xs,ys))c++;
        if(judge_cross(vec[2].x,vec[2].y,vec[0].x,vec[0].y,xk,yk,xs,ys))c++;
       //cout<<c<<endl;
        if(c==0||c==2){
            cout<<"NG"<<endl;
        }else{
            cout<<"OK"<<endl;
        }
    }
}

C++: #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <algorithm>

using namespace std;

#define rep(i,j) REP((i), 0, (j))
#define REP(i,j,k) for(int i=(j);(i)<(k);++i)
#define BW(a,x,b) ((a)<=(x)&&(x)<=(b))
#define F first
#define S second
#define INF 1 << 30

typedef pair<int, int> pi;
typedef pair<int, pi> pii;
typedef vector<int> vi;
typedef queue<int> qi;
typedef long long ll;

typedef struct POINT_tag{
  int x, y;
}POINT_t;

typedef struct LINT_tag{
  POINT_t a, b;
}LINE_t;

typedef struct TRIANGLE_tag{
  POINT_t a, b, c;
}TRIANGLE_t;

int side(POINT_t *p, LINE_t *e){
  POINT_t p1 = *p, p2 = e->a, p3 = e->b;

  const int n = p1.x * (p2.y - p3.y) + p2.x * (p3.y - p1.y) + p3.x * (p1.y - p2.y);
  if(n > 0) return 1;
  else if(n > 0) return -1;
  else return 0;
}

int solve(POINT_t *p, TRIANGLE_t *t){
  LINE_t ab, bc, ca;
  ab.a = t->a; ab.b = t->b;
  bc.a = t->b; bc.b = t->c;
  ca.a = t->c; ca.b = t->a;
  const int pab = side(p, &ab);
  const int pbc = side(p, &bc);
  const int pca = side(p, &ca);

  if((0 < pab) && (0 < pbc) && (0 < pca)) return 1;
  if((0 > pab) && (0 > pbc) && (0 > pca)) return 1;
  return 0;
}

int main(){
  int n;
  scanf("%d", &n);
  while(n--){
    TRIANGLE_t t;
    POINT_t k, s;
    scanf("%d%d%d%d%d%d%d%d%d%d", &t.a.x, &t.a.y, &t.b.x, &t.b.y, &t.c.x, &t.c.y, &k.x, &k.y, &s.x, &s.y);
    if(solve(&k, &t) != solve(&s, &t)) puts("OK");
    else puts("NG");
  }
  return 0;
}