//* Problem  : 
//* Date     : 2008.11.17
//* Author   : alt

// Geometry routines library

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <numeric>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <memory>
#include <string>
#include <vector>
#include <cctype>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
#include <algorithm>

using namespace std;

// to disable Visual C++ secure warnings
#pragma warning(disable : 4996)

///BEGIN CUT HERE
// types
typedef long long int64;
typedef unsigned long long uint64;
typedef pair <int,int> PII;
typedef vector <int> VI;
typedef vector <int64> VI64;
typedef vector <string> VS;
typedef vector <vector<string> > VVS;
typedef vector <vector<int> > VVI;
typedef vector <pair<int,int> > VPII;
typedef vector <vector<pair<int,int> > > VVPII;
typedef map<int, int > MII;
typedef map<string, int > MSI;
typedef queue<int > QI;
typedef queue<PII > QPII;
//loops
#define FOR(i, n) for (int i = 0; i < (int)(n); i++)
#define FORR(i, n) for (int i = (int)(n)-1; i >= 0; i--)
#define FORE(i, a, b) for (int i = (int)(a); i <= (int)(b); i++)
#define FORER(i, a, b) for (int i = (int)(a); i >= (int)(b); i--)
#define FORSZ(i, a) FOR(i, SZ(a))
#define FORSZR(i, a) FORR(SZ(a), i)
#define FORO(i, x) for (typeof((x).begin()) i = (x).begin(); i != (x).end(); i++)
#define FOROR(i, x) for (typeof((x).end()) i = (x).end(); i != (x).begin(); i--)
#define REP(n) for (int _foo = (int)(n) - 1; _foo >= 0; _foo--)
#define REP2(n) for (int _foo2 = (int)(n) - 1; _foo2 >= 0; _foo2--)

#define VAR(a, b) typeof(b) a=(b)
#define FOREACH(it, c) for(VAR(it,(c).begin()); it!=(c).end(); it++)
//sorting & c
#define ALL(a) a.begin(), a.end()
#define RALL(a) a.rbegin(), a.rend()
#define SORT(a) sort(ALL(a))
#define RSORT(a) sort(RALL(a))
#define UNIQUE(c) SORT(c),(c).resize(unique(ALL(c))-(c).begin())
#define REVERSE(a) reverse(ALL(a))
//filling
#define FLA(a,val) memset(a, val, sizeof(a))
#define FLO(o,val) memset(&o, val, sizeof(o))
#define CLA(a) FLA(a, 0)
#define CLO(a) FLO(a, 0)
//misc
#define _x first
#define _y second
#define MP make_pair
#define PB push_back
#define SZ(a) (int)a.size()
#define POP(a) a.top(), a.pop()
#define FRONT(a) a.front(), a.pop()
//const
const int INF = 1000000000;
const int64 INFL = 1000000000000000000LL;
const double PI = acos(-1.0);
const double EPS = 1E-9;

//some math
template <typename T> inline T gcd(T a, T b)				{ return b ? gcd(b, a % b) : a; }
template <typename T> inline T gcd2(T a, T b)				{ while (a && b) (a > b) ? a %= b : b %= a; return a + b;}
template <typename T> inline T lcm(T a, T b)				{ return a / gcd(a, b) * b; }
template <typename T> inline T abs(T a)					{ return a < 0 ? -a : a; }
template <typename T> inline T sqr(T a)					{ return a * a; }
template <typename T> inline double hypot(T a, T b)		{ return sqrt(1.0 * a * a + b * b);}
//template <typename T> inline double hypot(T a, T b, T ñ)	{ return sqrt(1.0 * a * a + b * b + ñ * ñ);}
template <typename T> inline T hypot2(T a, T b)			{ return a * a + b * b;}
//template <typename T> inline T hypot2(T a, T b, T c)		{ return a * a + b * b + c * c;}
template <typename T> inline void chMin(T& a, T b) { if (b < a) a = b; }
template <typename T> inline void chMax(T& a, T b) { if (b > a) a = b; }

//assertions
#ifdef _DEBUG
#define ASSERT(f) if (!(f)) printf("%s\n", "ASSERTION FAILED!");
#define ASSERTS(f, s) if (!(f)) printf("%s [%s]\n", "ASSERTION FAILED!", s);
#else
#define ASSERT(f) f
#define ASSERTS(f, s) f
#endif

int cmp_int(const void *a, const void *b){return *(int*)a - *(int*)b;}
int cmp_double(const void *a, const void *b){double t = *(double*)a - *(double*)b;return (fabs(t) < EPS) ? 0 : t > 0 ? 1 : -1;}
int cmp_int64(const void *a, const void *b){int64 t = *(int64*)a - *(int64*)b; return !t ? 0 : t > 0 ? 1 : -1;}

//input
inline void ri(int &tt){ASSERTS(scanf("%d", &tt) == 1, "ReadInt failed");}
inline int ri(){int tt; ASSERTS(scanf("%d", &tt) == 1, "ReadInt failed"); return tt;}
inline void ri64(int64 &tt){ASSERTS(scanf("%lld", &tt) == 1, "ReadInt64 failed");}
inline int64 ri64(){int64 tt; ASSERTS(scanf("%lld", &tt) == 1, "ReadInt64 failed"); return tt;}
inline void rd(double &tt){ASSERTS(scanf("%lf", &tt) == 1, "ReadDouble failed"); }
inline double rd(){double tt; ASSERTS(scanf("%lf", &tt) == 1, "ReadDouble failed"); return tt;}
inline void rs(char *s){ASSERTS(scanf("%s", s) == 1, "ReadChar* failed");}
//output
inline void pvi(int *a, int n){FOR(i, n) printf("%d%c", a[i], i == n - 1 ? '\n' : ' ');}
inline void pvi(VI a){FORSZ(i,a) printf("%d%c", a[i], i == a.size() - 1 ? '\n' : ' ');}
inline void pi(int n){printf("%d\n", n);}
inline void pi64(int64 n){printf("%lld\n", n);}

inline void _pi64(int64 n)
{
	if (n < 0) {putchar('-'); n = -n;}
	if (!n) {putchar('0'); return;}
	char stack[30]; int istack = 0;
	while (n)
	{
		stack[istack++] = (n % 10) + '0'; n /= 10;
	}
	while (istack > 0)
		putchar(stack[--istack]);
}
///END CUT HERE

#define EPS (1E-9)

struct Point
{
	// coordinates
	double x, y;
	
	// constructors
	Point(){x = y = 0.0;}
	Point(double x, double y) : x(x), y(y) {};

	// useful things
	void read(){scanf("%lf%lf", &x, &y);}
	void print(){printf("%.3lf %.3lf\n", x, y);}
	void inc(double d) {x += d; y += d;}
	void inc(double dx, double dy) {x += dx; y += dy;}

	// comparison operators
	bool operator<(const Point &other) const {return (abs(x - other.x) <= EPS) ? (abs(y - other.y) <= EPS) ? false : true : x < other.x;}
	bool operator==(const Point &other) const {return abs(x - other.x) <= EPS && abs(y - other.y) <= EPS;}

	// arithmetical operators
	Point operator+(const Point& value) const {Point result = *this; return result += value; }
	Point& operator+=(const Point& value) { x += value.x; y += value.y; }
	Point operator-(const Point& value) const { Point result = *this; return result -= value; }
	Point& operator-=(const Point& value) { x -= value.x; y -= value.y;}

	// basic operations
	double dist2(const Point &other) {return (x - other.x) * (x - other.x) + (y - other.y) * (y - other.y);}
	double dist(const Point &other) {return sqrt(dist2(other));}
	//double dist(const Line &line) {return line.dist(*this);}
	
	double polar_angle()
	{
	    double alpha = atan2(y, x);
		if (alpha < 0) alpha += 2 * PI;
		return alpha;
	}

	Point turnOXY(double alpha)
	{
		double c = cos(alpha);
		double s = sin(alpha);
		return Point(x * c - y * s, x * s + y * c);
	}

	Point turnPoint(Point base, double alpha)
	{
		Point res = *this - base;
		res.turnOXY(alpha);
		return res - base;
	}
};

struct Line
{
	double a, b, c;

	Line(){a = b = c = 0.0;}
	Line(double a, double b, double c) : a(a), b(b), c(c){}
	Line(Point p, Point q )
	{
		p1 = p; p2 = q;
		a = q.y - p.y;
		b = p.x - q.x;
		c = p.x * q.y - p.y * q.x;
	}
 

	Point p1, p2;

	bool operator<(const Line &other) const {return (abs(a - other.a) <= EPS) ? (abs(b - other.b) <= EPS) ? (abs(c - other.c) <= EPS)? false : c < other.c : b < other.b : a < other.a;}
	bool operator==(const Line &other) const {return abs(a - other.a) <= EPS && abs(b - other.b) <= EPS && abs(c - other.c) <= EPS;}

	int pointLinePosition(const Point &p) const
	{
		double s = p.x * a + p.y * b + c;
		return abs(s) <= EPS ? 0 : s > 0 ? 1 : -1;
	}

	bool parallelLine(const Line &line) const
	{
		return abs(line.a * b - line.b * a) <= EPS;
	}

	bool sameLine(const Line &line) const
	{
		return *this == line;
	}

	bool cross(const Line &line) const 
	{
		return !parallelLine(line);
	}

	Line normalTo(const Point &p) const
	{
		return Line(b, -a, -b * p.x + a * p.y);
	}

	Point closestPoint(const Point &p) const
	{
		double k = (a * p.x + b * p.y + c) / (a * a + b * b);
		return Point (p.x - a * k, p.y - b * k);
	}

	double dist(const Point &p) const
	{
		return abs((a * p.x + b * p.y + c) / sqrt(a * a + b * b));
	}

	double dist(const Line &l) const 
	{
		return abs(c - l.c) / sqrt(a * a + l.b * l.b);
	}

	Line getParallelLine(double dist) const
	{
		return Line(a, b, c - dist * sqrt(a * a + b * b));
	}
};

int Lines_Intersection_Coord(Line s1, Line s2, Point *res)
{
	double a1, a2, b1, b2, c1, c2, d, dx, dy;
	a1 = s1.p2.y - s1.p1.y; b1 = s1.p1.x - s1.p2.x;
	c1 = s1.p1.y * (s1.p2.x - s1.p1.x) - s1.p1.x * (s1.p2.y - s1.p1.y);
	a2 = s2.p2.y - s2.p1.y; b2 = s2.p1.x - s2.p2.x;
	c2 = s2.p1.y * (s2.p2.x - s2.p1.x) - s2.p1.x * (s2.p2.y - s2.p1.y);
	c1 = -c1; c2 = -c2;
	d = a1 * b2 - a2 * b1;
	if (fabs(d) < EPS) return 0;
	dx = c1 * b2 - c2 * b1;
	dy = a1 * c2 - c1 * a2;
	res->x = dx / d; res->y = dy / d;
	return 1;
}

int CollinearPoints(Point p1, Point p2, Point p3)
{
	return (fabs((p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y)) <= EPS);
}


int Point_Belongs_Segment(Line s, Point p)
{
	if (!CollinearPoints(s.p1, s.p2, p)) return 0;
	return ((p.x - s.p1.x) *  (p.x - s.p2.x) <= EPS && (p.y - s.p1.y) *  (p.y - s.p2.y) <= EPS);
}

int Segments_Intersection_Coord(Line s1, Line s2)
{
	Point t;
	if (!Lines_Intersection_Coord(s1, s2, &t)) return 0;
	if (Point_Belongs_Segment(s1, t) && Point_Belongs_Segment(s2, t))
	{
		return 1;
	}
	else return 0;
}



int n1, n2, res;

vector <Point> p1, p2;

int b[12];

int check_simple(vector <Point> a)
{
	int n = a.size();
	FOR(i,n)
	{
		int j = (i + 1) % n;
		Line L1 = Line(a[i], a[j]);
		FOR(i2, n)
		{
			int j2 = (i2 + 1) % n;
			if (i2 == i || i2 == j) continue;
			if (j2 == i || j2 == j) continue;
			Line L2 = Line(a[i2], a[j2]);
			if (Segments_Intersection_Coord(L1, L2)) return 0;
		}
	}
	return 1;
}

vector <vector <Point> > generate(vector <Point> a)
{
	int n = a.size();
	vector <vector <Point> > res;

	FOR(i,n) b[i] = i;

	do
	{
		vector <Point> t;
		FOR(i,n) t.PB(a[b[i]]);
		if (check_simple(t))
			res.PB(t);
	}
	while (next_permutation(b, b + n - 1));
	
	return res;
}

double SignAreaTriang(Point a, Point b, Point c)
{
	return (a.x*b.y - a.y*b.x + a.y*c.x - a.x*c.y + b.x*c.y - b.y*c.x)/(double)2;
}


bool ccw(Point a, Point b, Point c)
{
	return SignAreaTriang(a,b,c)>1e-7;
}

Point MinPy(Point a, Point b)
{
	return a.y<b.y || (a.y == b.y && a.x<b.x) ? a : b;
}

Point MaxPy(Point a, Point b)
{
	return a.y>b.y || (a.y == b.y && a.x>b.x) ? a : b;
}



int PointInPolygon(vector <Point> p, Point t, int fBorder)
{
	int i, j, count = 0, n = p.size();
	if (fBorder)
	{
		for (i = 0; i < n; i++)
		{
			j = (i + 1) % n;
			if (Point_Belongs_Segment(Line(p[i], p[j]), t)) return 1;
		}
	}

	for (i = 0; i < n; i++)
	{
		j = (i + 1) % n;
		count += (t.y > min(p[i].y, p[j].y) && t.y <= max(p[i].y, p[j].y) && ccw(MinPy(p[i], p[j]),MaxPy(p[i], p[j]), t));
	}
	return count&1;
}


int inters(vector <Point> a1, vector <Point> a2)
{
	int n1 = a1.size(), n2 = a2.size();
	FOR(i1, n1)
	{
		int j1 = (i1 + 1) % n1;
		Line L1(a1[i1], a1[j1]);
		FOR(i2, n2)
		{
			int j2 = (i2 + 1) % n2;
			Line L2 = Line(a2[i2], a2[j2]);
			if (Segments_Intersection_Coord(L1, L2)) return 1;
		}
	}

	//FOR(i, n1)
//		if (PointInPolygon(a2, a1[0], 1)) return 1;

	//FOR(i, n2)
//		if (PointInPolygon(a1, a2[0], 1)) return 1;

	return 0;
}

void solve()
{
	res = 1;
	vector <vector <Point> > vp1 = generate(p1);
	vector <vector <Point> > vp2 = generate(p2);
	//printf("%d - %d\n", vp1.size(), SZ(vp2));
	//return;
	FORSZ(k1, vp1) FORSZ(k2, vp2)
		if (!inters(vp1[k1], vp2[k2]))
		{
			//printf("%d %d\n", k1, k2);
			return;
		}
	res = 0;
	//FORSZ(k, vp1){FOR(i,n1) printf("%.0lf %.0lf ", vp1[k][i].x, vp1[k][i].y); printf("\n");}
}

int main()
{
#ifdef _DEBUG
	freopen("1064", "r", stdin);
#endif
	REP(ri())
	{
		p1.clear();
		p2.clear();
		n1 = ri();
		n2 = ri();
		FOR(i, n1) { Point t; t.read(); p1.PB(t);}
		FOR(i, n2) { Point t; t.read(); p2.PB(t);}
		solve();
		puts(res ? "YES" : "NO");
	}
	return 0;
}

