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

//-------------------------------------------------------------------------
// geometric library
 
namespace geometry {
 
#define EPS 1E-10 ///< 0とみなすサイズ。適当
 
    struct point {
        double x;
        double y;
 
		point() {}
		point(double x, double y) : x(x), y(y) {}
        point& operator += (const point& rhs) { x += rhs.x; y += rhs.y; return *this; }
        point& operator -= (const point& rhs) { x -= rhs.x; y -= rhs.y; return *this; }
        point& operator /= (double factor) { x /= factor; y /= factor; return *this; }
        point& operator *= (double factor) { x *= factor; y *= factor; return *this; }
        bool operator == (const point& rhs) const { return (std::abs(x - rhs.x) < EPS) && (std::abs(y - rhs.y) < EPS); }
        bool operator != (const point& rhs) const { return !(*this == rhs); }
        bool operator <= (const point& rhs) const { return x < rhs.x || (x == rhs.x && y <= rhs.y); }
        bool operator >= (const point& rhs) const { return x > rhs.x || (x == rhs.x && y >= rhs.y); }
        bool operator < (const point& rhs) const { return !(*this >= rhs); }
        bool operator > (const point& rhs) const { return !(*this <= rhs); }
		double arg() const { return atan2(y, x); }
        double norm() const { return sqrt(x * x + y * y); }
		point get_normal() const { return point(-y, x); }
    };

    point operator + (const point& p1, const point& p2)
    {
        point p(p1);
        p += p2;
        return p;
    }
 
    point operator / (const point& p1, double factor)
    {
        point p(p1);
        p /= factor;
        return p;
    }
  
    point operator * (const point& p1, double factor)
    {
        point p(p1);
        p *= factor;
        return p;
    }
 
    point operator * (double factor, const point& p1)
    {
        point p(p1);
        p *= factor;
        return p;
    }
 
    point operator - (const point& p1, const point& p2)
    {
        point p(p1);
        p -= p2;
        return p;
    }
 
    std::istream& operator >> (std::istream& is, point& p)
    {
        is >> p.x >> p.y;
        return is;
    }
 
    double cross_product(const point& p1, const point& p2)
    {
        return p1.x * p2.y - p2.x * p1.y;
    }

    enum rotate_dir {
        rotate_None = 0,
        rotate_CW = 1,
        rotate_CCW = -1
    };

    ///! p1-p2-p3が左右どちらの方向に折れているかを判定
    rotate_dir direction(const point& p1, const point& p2, const point& p3)
    {
        point p1_p3 = p1 - p3;
        point p2_p3 = p2 - p3;
        double cross = cross_product(p1_p3, p2_p3);
 
        if (std::abs(cross) < EPS) {
            return rotate_None;
        }
        else if (cross > 0) {
            return rotate_CW;
        }
        else {
            return rotate_CCW;
        }
    }

    // (p1s, p1e)と(p2s, p2e)の線分交差判定.EPS以下で接している場合はtrue、重なっている場合はfalse
    bool intersect(const point& p1s, const point& p1e, const point& p2s, const point& p2e)
    {
        assert(p1s != p1e && p2s != p2e);
        return
            (direction(p1s, p1e, p2s) != direction(p1s, p1e, p2e)) &&
            (direction(p2s, p2e, p1s) != direction(p2s, p2e, p1e));
    }

    // targetが三角形p1,p2,p3の内部にあるかどうか
    bool is_inside_triangle(const point& p1, const point& p2, const point& p3, const point& target)
    {
        point center_of_gravity = (p1 + p2 + p3) / 3; // 重心
 
        if (center_of_gravity == target) return true;
 
        // 重心とtargetを結んだ線分が三角形の辺と交叉するなら、点は三角形の外部にある
        bool intersect_any =
            intersect(p1, p2, center_of_gravity, target) ||
            intersect(p2, p3, center_of_gravity, target) ||
            intersect(p3, p1, center_of_gravity, target);
 
        return !intersect_any;
    }
} // namespace geometry


using namespace geometry;
using namespace std;

//-----------------------------------------------
//

class person {
public:
	person(const point& p) : m_p(p) {}
	const point& location() const { return m_p; }
private:
	point m_p;
};

class triangle_wall {
public:
	triangle_wall(const point points[3]) {
		std::copy(points, points + 3, m_p);
	}

	bool can_isolate(const person& p1, const person& p2) const {
		return is_inside_wall(p1.location()) != is_inside_wall(p2.location());
	}
private:
	bool is_inside_wall(const point& p) const {
		return is_inside_triangle(m_p[0], m_p[1], m_p[2], p);
	}
	point m_p[3];
};

//-----------------------------------------------
//

int main(void) {
	int n;
	point triangle[3];
	point pk, ps;

	cin >> n;

	for (int i = 0; i < n; i++) {
		cin >> triangle[0] >> triangle[1] >> triangle [2] >> pk >> ps;

		triangle_wall wall(triangle);
		person kengyu(pk), shokujyo(ps);

		cout << (wall.can_isolate(kengyu, shokujyo) ? "OK" : "NG") << endl;
	}
}