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

typedef long double DB;
const DB PI = acos(DB(-1));
const DB INF = 1e10;
const DB EPS = 1e-8;

inline DB sqr(DB x) {
	return x * x;
}

namespace G3{
	struct PT3 {
		DB x, y, z;

		PT3() {}
		PT3(DB x, DB y, DB z) : x(x), y(y), z(z) {}

		void in() {
			cin >> x >> y >> z;
		}
		DB len() {
			return sqrt(sqr(x) + sqr(y) + sqr(z));
		}
	};

	bool operator<(const PT3& p1, const PT3& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		if (fabs(p1.y - p2.y) > EPS) return p1.y < p2.y;
		return p1.z + EPS < p2.z;
	}

	bool operator==(const PT3& p1, const PT3& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS && fabs(p1.z - p2.z) < EPS;
	}

	PT3 operator-(PT3 p) {
		return PT3(-p.x, -p.y, -p.z);
	}

	PT3 operator+(PT3 p1, PT3 p2) {
		return PT3(p1.x + p2.x, p1.y + p2.y, p1.z + p2.z);
	}

	PT3 operator-(PT3 p1, PT3 p2) {
		return PT3(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z);
	}

	PT3 operator*(PT3 p, DB c) {
		return PT3(p.x * c, p.y * c, p.z * c);
	}

	PT3 operator/(PT3 p, DB c) {
		return PT3(p.x / c, p.y / c, p.z / c);
	}

	DB dist(PT3 P) {
		return P.len();
	}

	DB dis2(PT3 p1, PT3 p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y) + sqr(p1.z - p2.z);
	}

	DB dis(PT3 p1, PT3 p2) {
		return sqrt(dis2(p1, p2));
	}

	PT3 vect(PT3 p1, PT3 p2) {
		return PT3(p1.y * p2.z - p2.y * p1.z, -(p1.x * p2.z - p2.x * p1.z), p1.x * p2.y - p2.x * p1.y);
	}

	DB scal(PT3 p1, PT3 p2) {
		return p1.x * p2.x + p1.y * p2.y + p1.z * p2.z;
	}

	PT3 vect(PT3 p, PT3 p1, PT3 p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT3 p, PT3 p1, PT3 p2) {
		return scal(p1 - p, p2 - p);
	}
	//get norm of vector a
	PT3 normalize(PT3 a) {
		return a / sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
	}
	//get norm of virtically with plane abc.
	PT3 norm(PT3 a, PT3 b, PT3 c) {
		return normalize(vect(b - a, c - a)) ;
	}

	// Get Equation
	void GetEquation(PT3 A, PT3 B, PT3 C, DB &a, DB &b, DB &c, DB &d) {
		PT3 DIR = vect(B - A, C - A);
		a = DIR.x, b = DIR.y, c = DIR.z;
		d = - a * A.x - b * A.y - c * A.z;
	}

	DB GetValue(DB a, DB b, DB c, DB d, PT3 A) {
		return a * A.x + b * A.y + c * A.z + d;
	}

	// rotating points p* on plane abc to plane oxy;
	void rotate(PT3 *p, PT3 *q, int n, PT3 a, PT3 b, PT3 c) {
		PT3 pole = norm(a, b, c) ;
		PT3 polex;
		if (pole.x != 0 || pole.y != 0) polex = normalize(PT3(-pole.y, pole.x, 0));
		else polex = normalize(PT3(0, -pole.z, pole.y));
		PT3 poley = normalize(vect(pole, polex));
		DB hiv = scal(pole, p[0]);
		DB lov = hiv;
		for (int i = 0; i < n; i ++) {
			DB v = scal(pole, p[i]);
			hiv = max(v, hiv);
			lov = min(v, lov);
			DB x = scal(polex, p[i]);
			DB y = scal(poley, p[i]);
			DB z = scal(pole, p[i]);
			q[i] = PT3(x, y, z);
		}
	}

	DB disToPlane(PT3 p, DB a, DB b, DB c, DB d) {
		return abs(a * p.x + b * p.y + c * p.z + d) / sqrt(sqr(a) + sqr(b) + sqr(c));
	}

	// Projecting Point To Plane
	PT3 project(PT3 a, PT3 b, PT3 c, PT3 d) {
		PT3 tp = vect(b, c, d);
		return a - (tp * scal(tp, a - b) / scal(tp, tp));
	}

	void make_plane(PT3 p, PT3 p1, PT3 p2, DB& a, DB& b, DB& c, DB& d) {
		PT3 q = vect(p, p1, p2);
		a = q.x, b = q.y, c = q.z;
		d = -(a * p.x + b * p.y + c * p.z);
	}

	// Relation between Plane abc and Segment de
	int INTERSECT(PT3 a, PT3 b, PT3 c, PT3 d, PT3 e, PT3 &res) {
		/*
		Relation between Plain abc and Segment de...
		return 0: Pass by each other.
		return 1: Parallel but not contained.
		return 2: Intersect.
		return 3: Segment is contained on the plain.
		*/
		DB A, B, C, D;
		GetEquation(a, b, c, A, B, C, D);
		DB t1 = GetValue(A, B, C, D, d);
		DB t2 = GetValue(A, B, C, D, e);
		if (t1 > t2) swap(t1, t2), swap(d, e);
		if (fabs(t1) < EPS && fabs(t2) < EPS) {
			res = d;
			return 3;
		}
		if (fabs(t1) < EPS) {
			res = d;
			return 2;
		}
		if (fabs(t2) < EPS) {
			res = e;
			return 0;
		}
		if ((t1 > 0 && t2 > 0) || (t1 < 0 && t2 < 0)) {
			if (fabs(t1 - t2) < EPS) return 1;
			return 0;
		}
		DB Ratio = t1 / (t1 - t2);
		res = d + ((e - d) * Ratio);
		return 2;
	}
};
using namespace G3;

namespace G2{
	struct PT {
		DB x, y;

		PT() {}
		PT(DB x, DB y) : x(x), y(y) {}
	};

	bool operator<(const PT& p1, const PT& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		return p1.y + EPS < p2.y;
	}

	bool operator==(const PT& p1, const PT& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS;
	}

	PT operator+(PT p1, PT p2) {
		return PT(p1.x + p2.x, p1.y + p2.y);
	}

	PT operator-(PT p1, PT p2) {
		return PT(p1.x - p2.x, p1.y - p2.y);
	}

	PT operator*(PT p, DB c) {
		return PT(p.x * c, p.y * c);
	}

	PT operator/(PT p, DB c) {
		return PT(p.x / c, p.y / c);
	}

	DB dis(PT p) {
		return sqrt(sqr(p.x) + sqr(p.y));
	}

	DB dis2(PT p) {
		return sqr(p.x) + sqr(p.y);
	}

	PT rot(PT p, DB t) {
		return PT(p.x * cos(t) - p.y * sin(t), p.x * sin(t) + p.y * cos(t));
	}

	PT polar(PT p, DB r, DB t) {
		return PT(p.x + r * cos(t), p.y + r * sin(t));
	}

	DB dis2(PT p1, PT p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y);
	}

	DB dis(PT p1, PT p2) {
		return sqrt(dis2(p1, p2));
	}

	DB vect(PT p1, PT p2) {
		return p1.x * p2.y - p2.x * p1.y;
	}

	DB scal(PT p1, PT p2) {
		return p1.x * p2.x + p1.y * p2.y;
	}

	DB vect(PT p, PT p1, PT p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT p, PT p1, PT p2) {
		return scal(p1 - p, p2 - p);
	}

	bool onLine(PT p, PT p1, PT p2) {
		return fabs(vect(p1 - p, p2 - p)) < EPS;
	}

	bool onSeg(PT p, PT p1, PT p2) {
		if (!onLine(p, p1, p2)) return 0;
		return (p1.x - p.x) * (p2.x - p.x) < EPS && (p1.y - p.y) * (p2.y - p.y) < EPS;
	}

	PT projection(PT a, PT b, PT p) {
		return a + (a - b) * scal(p - a, a - b) / dis2(a - b);
	}

	int posLineLine(PT p1, PT p2, PT p3, PT p4, PT& p) {
		DB s1 = vect(p1, p2, p3), s2 = vect(p1, p2, p4);
		if (fabs(s1 - s2) < EPS) {
			if (fabs(s1) < EPS) return 2;
			return 0;
		}
		p = p3 + (p4 - p3) * s1 / (s1 - s2);
		return 1;
	}
};
using namespace G2;

const int N = 110000;
PT3 P[N], Q[N], _P[N], _Q[N];
PT p[N];

int main() {
//	freopen("in.txt", "r", stdin);
	ios_base::sync_with_stdio(0);
	int n, m; cin >> n;
	for (int i = 0; i < n; i++) P[i].in();
	cin >> m;
	for (int i = 0; i < m; i++) Q[i].in();
	rotate(P, _P, n, P[0], P[1], P[2]);
	rotate(Q, _Q, m, P[0], P[1], P[2]);
	for (int i = 0; i < n; i++) P[i] = _P[i], p[i] = PT(P[i].x, P[i].y);
	for (int i = 0; i < m; i++) Q[i] = _Q[i];
	int flg = 0;
	vector<PT> vec;
	for (int i = 0; i < m; i++) {
		PT3 res;
		if (INTERSECT(P[0], P[1], P[2], Q[i], Q[(i + 1) % m], res) == 2) vec.push_back(PT(res.x, res.y));
	}
	if (!vec.size() || flg) return puts("NO"), 0;
	if (vec.size() & 1) while (1);
	sort(vec.begin(), vec.end());
	PT A = vec[0], B = vec.back();
	DB l = dis(A, B);
	if (fabs(l) < EPS) return puts("NO"), 0;
	vector<DB> vd, vp;
	for (auto &t : vec) vd.push_back(dis(A, t) / l);
	for (int i = 0; i < n; i++) {
		PT res;
		int ret = posLineLine(p[i], p[(i + 1) % n], A, B, res);
		if (ret == 1 && onSeg(res, p[i], p[(i + 1) % n]) && dis(res, p[i]) > EPS) {
			DB d = dis(res, A) / l;
			if (onSeg(A, res, B)) d *= -1;
			vp.push_back(d);
		}
	}
	sort(vp.begin(), vp.end());
	assert(vp.size() % 2 == 0);
	int vn = 0, cnt = 0;
	for (int i = 0; i < vp.size(); i += 2) {
		DB from = vp[i], to = vp[i + 1];
		while (vn < vd.size() && vd[vn] < from) vn++;
		while (vn < vd.size() && vd[vn] < to) vn++, cnt++;
	}
	cnt & 1 ? puts("YES") : puts("NO");
}


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

typedef long double DB;
const DB PI = acos(DB(-1));
const DB INF = 1e10;
const DB EPS = 1e-8;

inline DB sqr(DB x) {
	return x * x;
}

namespace G3{
	struct PT3 {
		DB x, y, z;

		PT3() {}
		PT3(DB x, DB y, DB z) : x(x), y(y), z(z) {}

		void in() {
			cin >> x >> y >> z;
		}
		DB len() {
			return sqrt(sqr(x) + sqr(y) + sqr(z));
		}
	};

	bool operator<(const PT3& p1, const PT3& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		if (fabs(p1.y - p2.y) > EPS) return p1.y < p2.y;
		return p1.z + EPS < p2.z;
	}

	bool operator==(const PT3& p1, const PT3& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS && fabs(p1.z - p2.z) < EPS;
	}

	PT3 operator-(PT3 p) {
		return PT3(-p.x, -p.y, -p.z);
	}

	PT3 operator+(PT3 p1, PT3 p2) {
		return PT3(p1.x + p2.x, p1.y + p2.y, p1.z + p2.z);
	}

	PT3 operator-(PT3 p1, PT3 p2) {
		return PT3(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z);
	}

	PT3 operator*(PT3 p, DB c) {
		return PT3(p.x * c, p.y * c, p.z * c);
	}

	PT3 operator/(PT3 p, DB c) {
		return PT3(p.x / c, p.y / c, p.z / c);
	}

	DB dist(PT3 P) {
		return P.len();
	}

	DB dis2(PT3 p1, PT3 p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y) + sqr(p1.z - p2.z);
	}

	DB dis(PT3 p1, PT3 p2) {
		return sqrt(dis2(p1, p2));
	}

	PT3 vect(PT3 p1, PT3 p2) {
		return PT3(p1.y * p2.z - p2.y * p1.z, -(p1.x * p2.z - p2.x * p1.z), p1.x * p2.y - p2.x * p1.y);
	}

	DB scal(PT3 p1, PT3 p2) {
		return p1.x * p2.x + p1.y * p2.y + p1.z * p2.z;
	}

	PT3 vect(PT3 p, PT3 p1, PT3 p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT3 p, PT3 p1, PT3 p2) {
		return scal(p1 - p, p2 - p);
	}
	//get norm of vector a
	PT3 normalize(PT3 a) {
		return a / sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
	}
	//get norm of virtically with plane abc.
	PT3 norm(PT3 a, PT3 b, PT3 c) {
		return normalize(vect(b - a, c - a)) ;
	}

	// Get Equation
	void GetEquation(PT3 A, PT3 B, PT3 C, DB &a, DB &b, DB &c, DB &d) {
		PT3 DIR = vect(B - A, C - A);
		a = DIR.x, b = DIR.y, c = DIR.z;
		d = - a * A.x - b * A.y - c * A.z;
	}

	DB GetValue(DB a, DB b, DB c, DB d, PT3 A) {
		return a * A.x + b * A.y + c * A.z + d;
	}

	// rotating points p* on plane abc to plane oxy;
	void rotate(PT3 *p, PT3 *q, int n, PT3 a, PT3 b, PT3 c) {
		PT3 pole = norm(a, b, c) ;
		PT3 polex;
		if (pole.x != 0 || pole.y != 0) polex = normalize(PT3(-pole.y, pole.x, 0));
		else polex = normalize(PT3(0, -pole.z, pole.y));
		PT3 poley = normalize(vect(pole, polex));
		DB hiv = scal(pole, p[0]);
		DB lov = hiv;
		for (int i = 0; i < n; i ++) {
			DB v = scal(pole, p[i]);
			hiv = max(v, hiv);
			lov = min(v, lov);
			DB x = scal(polex, p[i]);
			DB y = scal(poley, p[i]);
			DB z = scal(pole, p[i]);
			q[i] = PT3(x, y, z);
		}
	}

	DB disToPlane(PT3 p, DB a, DB b, DB c, DB d) {
		return abs(a * p.x + b * p.y + c * p.z + d) / sqrt(sqr(a) + sqr(b) + sqr(c));
	}

	// Projecting Point To Plane
	PT3 project(PT3 a, PT3 b, PT3 c, PT3 d) {
		PT3 tp = vect(b, c, d);
		return a - (tp * scal(tp, a - b) / scal(tp, tp));
	}

	void make_plane(PT3 p, PT3 p1, PT3 p2, DB& a, DB& b, DB& c, DB& d) {
		PT3 q = vect(p, p1, p2);
		a = q.x, b = q.y, c = q.z;
		d = -(a * p.x + b * p.y + c * p.z);
	}

	// Relation between Plane abc and Segment de
	int INTERSECT(PT3 a, PT3 b, PT3 c, PT3 d, PT3 e, PT3 &res) {
		/*
		Relation between Plain abc and Segment de...
		return 0: Pass by each other.
		return 1: Parallel but not contained.
		return 2: Intersect.
		return 3: Segment is contained on the plain.
		*/
		DB A, B, C, D;
		GetEquation(a, b, c, A, B, C, D);
		DB t1 = GetValue(A, B, C, D, d);
		DB t2 = GetValue(A, B, C, D, e);
		if (fabs(t1) < EPS && fabs(t2) < EPS) {
			res = d;
			return 3;
		}
		if (fabs(t1) < EPS) {
			res = d;
			return 2;
		}
		if (fabs(t2) < EPS) {
			res = e;
			return 2;
		}
		if ((t1 > 0 && t2 > 0) || (t1 < 0 && t2 < 0)) {
			if (fabs(t1 - t2) < EPS) return 1;
			return 0;
		}
		DB Ratio = t1 / (t1 - t2);
		res = d + ((e - d) * Ratio);
		return 2;
	}
};
using namespace G3;

namespace G2{
	struct PT {
		DB x, y;

		PT() {}
		PT(DB x, DB y) : x(x), y(y) {}
	};

	bool operator<(const PT& p1, const PT& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		return p1.y + EPS < p2.y;
	}

	bool operator==(const PT& p1, const PT& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS;
	}

	PT operator+(PT p1, PT p2) {
		return PT(p1.x + p2.x, p1.y + p2.y);
	}

	PT operator-(PT p1, PT p2) {
		return PT(p1.x - p2.x, p1.y - p2.y);
	}

	PT operator*(PT p, DB c) {
		return PT(p.x * c, p.y * c);
	}

	PT operator/(PT p, DB c) {
		return PT(p.x / c, p.y / c);
	}

	DB dis(PT p) {
		return sqrt(sqr(p.x) + sqr(p.y));
	}

	DB dis2(PT p) {
		return sqr(p.x) + sqr(p.y);
	}

	PT rot(PT p, DB t) {
		return PT(p.x * cos(t) - p.y * sin(t), p.x * sin(t) + p.y * cos(t));
	}

	PT polar(PT p, DB r, DB t) {
		return PT(p.x + r * cos(t), p.y + r * sin(t));
	}

	DB dis2(PT p1, PT p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y);
	}

	DB dis(PT p1, PT p2) {
		return sqrt(dis2(p1, p2));
	}

	DB vect(PT p1, PT p2) {
		return p1.x * p2.y - p2.x * p1.y;
	}

	DB scal(PT p1, PT p2) {
		return p1.x * p2.x + p1.y * p2.y;
	}

	DB vect(PT p, PT p1, PT p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT p, PT p1, PT p2) {
		return scal(p1 - p, p2 - p);
	}

	bool onLine(PT p, PT p1, PT p2) {
		return fabs(vect(p1 - p, p2 - p)) < EPS;
	}

	bool onSeg(PT p, PT p1, PT p2) {
		if (!onLine(p, p1, p2)) return 0;
		return (p1.x - p.x) * (p2.x - p.x) < EPS && (p1.y - p.y) * (p2.y - p.y) < EPS;
	}

	PT projection(PT a, PT b, PT p) {
		return a + (a - b) * scal(p - a, a - b) / dis2(a - b);
	}

	int posLineLine(PT p1, PT p2, PT p3, PT p4, PT& p) {
		DB s1 = vect(p1, p2, p3), s2 = vect(p1, p2, p4);
		if (fabs(s1 - s2) < EPS) {
			if (fabs(s1) < EPS) return 2;
			return 0;
		}
		p = p3 + (p4 - p3) * s1 / (s1 - s2);
		return 1;
	}
};
using namespace G2;

const int N = 110000;
PT3 P[N], Q[N], _P[N], _Q[N];
PT p[N];

int main() {
//	freopen("in.txt", "r", stdin);
	ios_base::sync_with_stdio(0);
	int n, m; cin >> n;
	for (int i = 0; i < n; i++) P[i].in();
	cin >> m;
	for (int i = 0; i < m; i++) Q[i].in();
	rotate(P, _P, n, P[0], P[1], P[2]);
	rotate(Q, _Q, m, P[0], P[1], P[2]);
	for (int i = 0; i < n; i++) P[i] = _P[i], p[i] = PT(P[i].x, P[i].y);
	for (int i = 0; i < m; i++) Q[i] = _Q[i];
	int flg = 0;
	vector<PT> vec;
	for (int i = 0; i < m; i++) {
		PT3 res;
		if (INTERSECT(P[0], P[1], P[2], Q[i], Q[(i + 1) % m], res) == 2) vec.push_back(PT(res.x, res.y));
	}
	if (!vec.size() || flg) return puts("NO"), 0;
	if (vec.size() & 1) while (1);
	sort(vec.begin(), vec.end());
	PT A = vec[0], B = vec.back();
	DB l = dis(A, B);
	if (fabs(l) < EPS) return puts("NO"), 0;
	vector<DB> vd, vp;
	for (auto &t : vec) vd.push_back(dis(A, t) / l);
	for (int i = 0; i < n; i++) {
		PT res;
		int ret = posLineLine(p[i], p[(i + 1) % n], A, B, res);
		if (ret == 1 && onSeg(res, p[i], p[(i + 1) % n])) {
			DB d = dis(res, A) / l;
			if (onSeg(A, res, B)) d *= -1;
			vp.push_back(d);
		}
	}
	sort(vp.begin(), vp.end());
	assert(vp.size() % 2 == 0);
	int vn = 0, cnt = 0;
	for (int i = 0; i < vp.size(); i += 2) {
		DB from = vp[i], to = vp[i + 1];
		while (vn < vd.size() && vd[vn] < from) vn++;
		while (vn < vd.size() && vd[vn] < to) vn++, cnt++;
	}
	cnt & 1 ? puts("YES") : puts("NO");
}


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

typedef long double DB;
const DB PI = acos(DB(-1));
const DB INF = 1e10;
const DB EPS = 1e-8;

inline DB sqr(DB x) {
	return x * x;
}

namespace G3{
	struct PT3 {
		DB x, y, z;

		PT3() {}
		PT3(DB x, DB y, DB z) : x(x), y(y), z(z) {}

		void in() {
			cin >> x >> y >> z;
		}
		DB len() {
			return sqrt(sqr(x) + sqr(y) + sqr(z));
		}
	};

	bool operator<(const PT3& p1, const PT3& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		if (fabs(p1.y - p2.y) > EPS) return p1.y < p2.y;
		return p1.z + EPS < p2.z;
	}

	bool operator==(const PT3& p1, const PT3& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS && fabs(p1.z - p2.z) < EPS;
	}

	PT3 operator-(PT3 p) {
		return PT3(-p.x, -p.y, -p.z);
	}

	PT3 operator+(PT3 p1, PT3 p2) {
		return PT3(p1.x + p2.x, p1.y + p2.y, p1.z + p2.z);
	}

	PT3 operator-(PT3 p1, PT3 p2) {
		return PT3(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z);
	}

	PT3 operator*(PT3 p, DB c) {
		return PT3(p.x * c, p.y * c, p.z * c);
	}

	PT3 operator/(PT3 p, DB c) {
		return PT3(p.x / c, p.y / c, p.z / c);
	}

	DB dist(PT3 P) {
		return P.len();
	}

	DB dis2(PT3 p1, PT3 p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y) + sqr(p1.z - p2.z);
	}

	DB dis(PT3 p1, PT3 p2) {
		return sqrt(dis2(p1, p2));
	}

	PT3 vect(PT3 p1, PT3 p2) {
		return PT3(p1.y * p2.z - p2.y * p1.z, -(p1.x * p2.z - p2.x * p1.z), p1.x * p2.y - p2.x * p1.y);
	}

	DB scal(PT3 p1, PT3 p2) {
		return p1.x * p2.x + p1.y * p2.y + p1.z * p2.z;
	}

	PT3 vect(PT3 p, PT3 p1, PT3 p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT3 p, PT3 p1, PT3 p2) {
		return scal(p1 - p, p2 - p);
	}
	//get norm of vector a
	PT3 normalize(PT3 a) {
		return a / sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
	}
	//get norm of virtically with plane abc.
	PT3 norm(PT3 a, PT3 b, PT3 c) {
		return normalize(vect(b - a, c - a)) ;
	}

	// Get Equation
	void GetEquation(PT3 A, PT3 B, PT3 C, DB &a, DB &b, DB &c, DB &d) {
		PT3 DIR = vect(B - A, C - A);
		a = DIR.x, b = DIR.y, c = DIR.z;
		d = - a * A.x - b * A.y - c * A.z;
	}

	DB GetValue(DB a, DB b, DB c, DB d, PT3 A) {
		return a * A.x + b * A.y + c * A.z + d;
	}

	// rotating points p* on plane abc to plane oxy;
	void rotate(PT3 *p, PT3 *q, int n, PT3 a, PT3 b, PT3 c) {
		PT3 pole = norm(a, b, c) ;
		PT3 polex;
		if (pole.x != 0 || pole.y != 0) polex = normalize(PT3(-pole.y, pole.x, 0));
		else polex = normalize(PT3(0, -pole.z, pole.y));
		PT3 poley = normalize(vect(pole, polex));
		DB hiv = scal(pole, p[0]);
		DB lov = hiv;
		for (int i = 0; i < n; i ++) {
			DB v = scal(pole, p[i]);
			hiv = max(v, hiv);
			lov = min(v, lov);
			DB x = scal(polex, p[i]);
			DB y = scal(poley, p[i]);
			DB z = scal(pole, p[i]);
			q[i] = PT3(x, y, z);
		}
	}

	DB disToPlane(PT3 p, DB a, DB b, DB c, DB d) {
		return abs(a * p.x + b * p.y + c * p.z + d) / sqrt(sqr(a) + sqr(b) + sqr(c));
	}

	// Projecting Point To Plane
	PT3 project(PT3 a, PT3 b, PT3 c, PT3 d) {
		PT3 tp = vect(b, c, d);
		return a - (tp * scal(tp, a - b) / scal(tp, tp));
	}

	void make_plane(PT3 p, PT3 p1, PT3 p2, DB& a, DB& b, DB& c, DB& d) {
		PT3 q = vect(p, p1, p2);
		a = q.x, b = q.y, c = q.z;
		d = -(a * p.x + b * p.y + c * p.z);
	}

	// Relation between Plane abc and Segment de
	int INTERSECT(PT3 a, PT3 b, PT3 c, PT3 d, PT3 e, PT3 &res) {
		/*
		Relation between Plain abc and Segment de...
		return 0: Pass by each other.
		return 1: Parallel but not contained.
		return 2: Intersect.
		return 3: Segment is contained on the plain.
		*/
		DB A, B, C, D;
		GetEquation(a, b, c, A, B, C, D);
		DB t1 = GetValue(A, B, C, D, d);
		DB t2 = GetValue(A, B, C, D, e);
		if (fabs(t1) < EPS && fabs(t2) < EPS) {
			res = d;
			return 3;
		}
		if (fabs(t1) < EPS) {
			res = d;
			return 2;
		}
		if (fabs(t2) < EPS) {
			res = e;
			return 2;
		}
		if ((t1 > 0 && t2 > 0) || (t1 < 0 && t2 < 0)) {
			if (fabs(t1 - t2) < EPS) return 1;
			return 0;
		}
		DB Ratio = t1 / (t1 - t2);
		res = d + ((e - d) * Ratio);
		return 2;
	}
};
using namespace G3;

namespace G2{
	struct PT {
		DB x, y;

		PT() {}
		PT(DB x, DB y) : x(x), y(y) {}
	};

	bool operator<(const PT& p1, const PT& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		return p1.y + EPS < p2.y;
	}

	bool operator==(const PT& p1, const PT& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS;
	}

	PT operator+(PT p1, PT p2) {
		return PT(p1.x + p2.x, p1.y + p2.y);
	}

	PT operator-(PT p1, PT p2) {
		return PT(p1.x - p2.x, p1.y - p2.y);
	}

	PT operator*(PT p, DB c) {
		return PT(p.x * c, p.y * c);
	}

	PT operator/(PT p, DB c) {
		return PT(p.x / c, p.y / c);
	}

	DB dis(PT p) {
		return sqrt(sqr(p.x) + sqr(p.y));
	}

	DB dis2(PT p) {
		return sqr(p.x) + sqr(p.y);
	}

	PT rot(PT p, DB t) {
		return PT(p.x * cos(t) - p.y * sin(t), p.x * sin(t) + p.y * cos(t));
	}

	PT polar(PT p, DB r, DB t) {
		return PT(p.x + r * cos(t), p.y + r * sin(t));
	}

	DB dis2(PT p1, PT p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y);
	}

	DB dis(PT p1, PT p2) {
		return sqrt(dis2(p1, p2));
	}

	DB vect(PT p1, PT p2) {
		return p1.x * p2.y - p2.x * p1.y;
	}

	DB scal(PT p1, PT p2) {
		return p1.x * p2.x + p1.y * p2.y;
	}

	DB vect(PT p, PT p1, PT p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT p, PT p1, PT p2) {
		return scal(p1 - p, p2 - p);
	}

	bool onLine(PT p, PT p1, PT p2) {
		return fabs(vect(p1 - p, p2 - p)) < EPS;
	}

	bool onSeg(PT p, PT p1, PT p2) {
		if (!onLine(p, p1, p2)) return 0;
		return (p1.x - p.x) * (p2.x - p.x) < EPS && (p1.y - p.y) * (p2.y - p.y) < EPS;
	}

	PT projection(PT a, PT b, PT p) {
		return a + (a - b) * scal(p - a, a - b) / dis2(a - b);
	}

	int posLineLine(PT p1, PT p2, PT p3, PT p4, PT& p) {
		DB s1 = vect(p1, p2, p3), s2 = vect(p1, p2, p4);
		if (fabs(s1 - s2) < EPS) {
			if (fabs(s1) < EPS) return 2;
			return 0;
		}
		p = p3 + (p4 - p3) * s1 / (s1 - s2);
		return 1;
	}
};
using namespace G2;

const int N = 110000;
PT3 P[N], Q[N], _P[N], _Q[N];
PT p[N];

int main() {
//	freopen("in.txt", "r", stdin);
	ios_base::sync_with_stdio(0);
	int n, m; cin >> n;
	for (int i = 0; i < n; i++) P[i].in();
	cin >> m;
	for (int i = 0; i < m; i++) Q[i].in();
	rotate(P, _P, n, P[0], P[1], P[2]);
	rotate(Q, _Q, m, P[0], P[1], P[2]);
	for (int i = 0; i < n; i++) P[i] = _P[i], p[i] = PT(P[i].x, P[i].y);
	for (int i = 0; i < m; i++) Q[i] = _Q[i];
	int flg = 0;
	vector<PT> vec;
	for (int i = 0; i < m; i++) {
		PT3 res;
		if (INTERSECT(P[0], P[1], P[2], Q[i], Q[(i + 1) % m], res) == 2) vec.push_back(PT(res.x, res.y));
	}
	if (!vec.size() || flg) return puts("NO"), 0;
//	if (vec.size() & 1) while (1);
	sort(vec.begin(), vec.end());
	PT A = vec[0], B = vec.back();
	DB l = dis(A, B);
	if (fabs(l) < EPS) return puts("NO"), 0;
	vector<DB> vd, vp;
	for (auto &t : vec) vd.push_back(dis(A, t) / l);
	for (int i = 0; i < n; i++) {
		PT res;
		int ret = posLineLine(p[i], p[(i + 1) % n], A, B, res);
		if (ret == 1 && onSeg(res, p[i], p[(i + 1) % n])) {
			DB d = dis(res, A) / l;
			if (onSeg(A, res, B)) d *= -1;
			vp.push_back(d);
		}
	}
	sort(vp.begin(), vp.end());
//	assert(vp.size() % 2 == 0);
	int vn = 0, cnt = 0;
	for (int i = 0; i < vp.size(); i += 2) {
		DB from = vp[i], to = vp[i + 1];
		while (vn < vd.size() && vd[vn] < from) vn++;
		while (vn < vd.size() && vd[vn] < to) vn++, cnt++;
	}
	cnt & 1 ? puts("YES") : puts("NO");
}


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

typedef long double DB;
const DB PI = acos(DB(-1));
const DB INF = 1e10;
const DB EPS = 1e-8;

inline DB sqr(DB x) {
	return x * x;
}

namespace G3{
	struct PT3 {
		DB x, y, z;

		PT3() {}
		PT3(DB x, DB y, DB z) : x(x), y(y), z(z) {}

		void in() {
			cin >> x >> y >> z;
		}
		DB len() {
			return sqrt(sqr(x) + sqr(y) + sqr(z));
		}
	};

	bool operator<(const PT3& p1, const PT3& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		if (fabs(p1.y - p2.y) > EPS) return p1.y < p2.y;
		return p1.z + EPS < p2.z;
	}

	bool operator==(const PT3& p1, const PT3& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS && fabs(p1.z - p2.z) < EPS;
	}

	PT3 operator-(PT3 p) {
		return PT3(-p.x, -p.y, -p.z);
	}

	PT3 operator+(PT3 p1, PT3 p2) {
		return PT3(p1.x + p2.x, p1.y + p2.y, p1.z + p2.z);
	}

	PT3 operator-(PT3 p1, PT3 p2) {
		return PT3(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z);
	}

	PT3 operator*(PT3 p, DB c) {
		return PT3(p.x * c, p.y * c, p.z * c);
	}

	PT3 operator/(PT3 p, DB c) {
		return PT3(p.x / c, p.y / c, p.z / c);
	}

	DB dist(PT3 P) {
		return P.len();
	}

	DB dis2(PT3 p1, PT3 p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y) + sqr(p1.z - p2.z);
	}

	DB dis(PT3 p1, PT3 p2) {
		return sqrt(dis2(p1, p2));
	}

	PT3 vect(PT3 p1, PT3 p2) {
		return PT3(p1.y * p2.z - p2.y * p1.z, -(p1.x * p2.z - p2.x * p1.z), p1.x * p2.y - p2.x * p1.y);
	}

	DB scal(PT3 p1, PT3 p2) {
		return p1.x * p2.x + p1.y * p2.y + p1.z * p2.z;
	}

	PT3 vect(PT3 p, PT3 p1, PT3 p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT3 p, PT3 p1, PT3 p2) {
		return scal(p1 - p, p2 - p);
	}
	//get norm of vector a
	PT3 normalize(PT3 a) {
		return a / sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
	}
	//get norm of virtically with plane abc.
	PT3 norm(PT3 a, PT3 b, PT3 c) {
		return normalize(vect(b - a, c - a)) ;
	}

	// Get Equation
	void GetEquation(PT3 A, PT3 B, PT3 C, DB &a, DB &b, DB &c, DB &d) {
		PT3 DIR = vect(B - A, C - A);
		a = DIR.x, b = DIR.y, c = DIR.z;
		d = - a * A.x - b * A.y - c * A.z;
	}

	DB GetValue(DB a, DB b, DB c, DB d, PT3 A) {
		return a * A.x + b * A.y + c * A.z + d;
	}

	// rotating points p* on plane abc to plane oxy;
	void rotate(PT3 *p, PT3 *q, int n, PT3 a, PT3 b, PT3 c) {
		PT3 pole = norm(a, b, c) ;
		PT3 polex;
		if (pole.x != 0 || pole.y != 0) polex = normalize(PT3(-pole.y, pole.x, 0));
		else polex = normalize(PT3(0, -pole.z, pole.y));
		PT3 poley = normalize(vect(pole, polex));
		DB hiv = scal(pole, p[0]);
		DB lov = hiv;
		for (int i = 0; i < n; i ++) {
			DB v = scal(pole, p[i]);
			hiv = max(v, hiv);
			lov = min(v, lov);
			DB x = scal(polex, p[i]);
			DB y = scal(poley, p[i]);
			DB z = scal(pole, p[i]);
			q[i] = PT3(x, y, z);
		}
	}

	DB disToPlane(PT3 p, DB a, DB b, DB c, DB d) {
		return abs(a * p.x + b * p.y + c * p.z + d) / sqrt(sqr(a) + sqr(b) + sqr(c));
	}

	// Projecting Point To Plane
	PT3 project(PT3 a, PT3 b, PT3 c, PT3 d) {
		PT3 tp = vect(b, c, d);
		return a - (tp * scal(tp, a - b) / scal(tp, tp));
	}

	void make_plane(PT3 p, PT3 p1, PT3 p2, DB& a, DB& b, DB& c, DB& d) {
		PT3 q = vect(p, p1, p2);
		a = q.x, b = q.y, c = q.z;
		d = -(a * p.x + b * p.y + c * p.z);
	}

	// Relation between Plane abc and Segment de
	int INTERSECT(PT3 a, PT3 b, PT3 c, PT3 d, PT3 e, PT3 &res) {
		/*
		Relation between Plain abc and Segment de...
		return 0: Pass by each other.
		return 1: Parallel but not contained.
		return 2: Intersect.
		return 3: Segment is contained on the plain.
		*/
		DB A, B, C, D;
		GetEquation(a, b, c, A, B, C, D);
		DB t1 = GetValue(A, B, C, D, d);
		DB t2 = GetValue(A, B, C, D, e);
		if (fabs(t1) < EPS && fabs(t2) < EPS) {
			res = d;
			return 3;
		}
		if (fabs(t1) < EPS) {
			res = d;
			return 2;
		}
		if (fabs(t2) < EPS) {
			res = e;
			return 2;
		}
		if ((t1 > 0 && t2 > 0) || (t1 < 0 && t2 < 0)) {
			if (fabs(t1 - t2) < EPS) return 1;
			return 0;
		}
		DB Ratio = t1 / (t1 - t2);
		res = d + ((e - d) * Ratio);
		return 2;
	}
};
using namespace G3;

namespace G2{
	struct PT {
		DB x, y;

		PT() {}
		PT(DB x, DB y) : x(x), y(y) {}
	};

	bool operator<(const PT& p1, const PT& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		return p1.y + EPS < p2.y;
	}

	bool operator==(const PT& p1, const PT& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS;
	}

	PT operator+(PT p1, PT p2) {
		return PT(p1.x + p2.x, p1.y + p2.y);
	}

	PT operator-(PT p1, PT p2) {
		return PT(p1.x - p2.x, p1.y - p2.y);
	}

	PT operator*(PT p, DB c) {
		return PT(p.x * c, p.y * c);
	}

	PT operator/(PT p, DB c) {
		return PT(p.x / c, p.y / c);
	}

	DB dis(PT p) {
		return sqrt(sqr(p.x) + sqr(p.y));
	}

	DB dis2(PT p) {
		return sqr(p.x) + sqr(p.y);
	}

	PT rot(PT p, DB t) {
		return PT(p.x * cos(t) - p.y * sin(t), p.x * sin(t) + p.y * cos(t));
	}

	PT polar(PT p, DB r, DB t) {
		return PT(p.x + r * cos(t), p.y + r * sin(t));
	}

	DB dis2(PT p1, PT p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y);
	}

	DB dis(PT p1, PT p2) {
		return sqrt(dis2(p1, p2));
	}

	DB vect(PT p1, PT p2) {
		return p1.x * p2.y - p2.x * p1.y;
	}

	DB scal(PT p1, PT p2) {
		return p1.x * p2.x + p1.y * p2.y;
	}

	DB vect(PT p, PT p1, PT p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT p, PT p1, PT p2) {
		return scal(p1 - p, p2 - p);
	}

	bool onLine(PT p, PT p1, PT p2) {
		return fabs(vect(p1 - p, p2 - p)) < EPS;
	}

	bool onSeg(PT p, PT p1, PT p2) {
		if (!onLine(p, p1, p2)) return 0;
		return (p1.x - p.x) * (p2.x - p.x) < EPS && (p1.y - p.y) * (p2.y - p.y) < EPS;
	}

	PT projection(PT a, PT b, PT p) {
		return a + (a - b) * scal(p - a, a - b) / dis2(a - b);
	}

	int posLineLine(PT p1, PT p2, PT p3, PT p4, PT& p) {
		DB s1 = vect(p1, p2, p3), s2 = vect(p1, p2, p4);
		if (fabs(s1 - s2) < EPS) {
			if (fabs(s1) < EPS) return 2;
			return 0;
		}
		p = p3 + (p4 - p3) * s1 / (s1 - s2);
		return 1;
	}
};
using namespace G2;

const int N = 110000;
PT3 P[N], Q[N], _P[N], _Q[N];
PT p[N];

int main() {
//	freopen("in.txt", "r", stdin);
	ios_base::sync_with_stdio(0);
	int n, m; cin >> n;
	for (int i = 0; i < n; i++) P[i].in();
	cin >> m;
	for (int i = 0; i < m; i++) Q[i].in();
	rotate(P, _P, n, P[0], P[1], P[2]);
	rotate(Q, _Q, m, P[0], P[1], P[2]);
	for (int i = 0; i < n; i++) P[i] = _P[i], p[i] = PT(P[i].x, P[i].y);
	for (int i = 0; i < m; i++) Q[i] = _Q[i];
	int flg = 0;
	vector<PT> vec;
	for (int i = 0; i < m; i++) {
		PT3 res;
		if (INTERSECT(P[0], P[1], P[2], Q[i], Q[(i + 1) % m], res) == 2) vec.push_back(PT(res.x, res.y));
	}
	if (!vec.size() || flg) return puts("NO"), 0;
	PT A = vec[0], B = vec.back();
	DB l = dis(A, B);
	vector<DB> vd, vp;
	for (auto &t : vec) vd.push_back(dis(A, t) / l);
	for (int i = 0; i < n; i++) {
		PT res;
		int ret = posLineLine(p[i], p[(i + 1) % n], A, B, res);
		if (ret == 1 && onSeg(res, p[i], p[(i + 1) % n])) {
			DB d = dis(res, A) / l;
			if (onSeg(A, res, B)) d *= -1;
			vp.push_back(d);
		}
	}
	sort(vp.begin(), vp.end());
	assert(vp.size() % 2 == 0);
	int vn = 0, cnt = 0;
	for (int i = 0; i < vp.size(); i += 2) {
		DB from = vp[i], to = vp[i + 1];
		while (vn < vd.size() && vd[vn] < from) vn++;
		while (vn < vd.size() && vd[vn] < to) vn++, cnt++;
	}
	cnt & 1 ? puts("YES") : puts("NO");
}


#include<bits/stdc++.h>
#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
using namespace std;

typedef double DB;
const DB PI = acos(DB(-1));
const DB INF = 1e10;
const DB EPS = 1e-8;

inline DB sqr(DB x) {
	return x * x;
}

namespace G3{
	struct PT3 {
		DB x, y, z;

		PT3() {}
		PT3(DB x, DB y, DB z) : x(x), y(y), z(z) {}

		void in() {
			scanf("%lf%lf%lf", &x, &y, &z);
		}
		DB len() {
			return sqrt(sqr(x) + sqr(y) + sqr(z));
		}
	};

	bool operator<(const PT3& p1, const PT3& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		if (fabs(p1.y - p2.y) > EPS) return p1.y < p2.y;
		return p1.z + EPS < p2.z;
	}

	bool operator==(const PT3& p1, const PT3& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS && fabs(p1.z - p2.z) < EPS;
	}

	PT3 operator-(PT3 p) {
		return PT3(-p.x, -p.y, -p.z);
	}

	PT3 operator+(PT3 p1, PT3 p2) {
		return PT3(p1.x + p2.x, p1.y + p2.y, p1.z + p2.z);
	}

	PT3 operator-(PT3 p1, PT3 p2) {
		return PT3(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z);
	}

	PT3 operator*(PT3 p, DB c) {
		return PT3(p.x * c, p.y * c, p.z * c);
	}

	PT3 operator/(PT3 p, DB c) {
		return PT3(p.x / c, p.y / c, p.z / c);
	}

	DB dist(PT3 P) {
		return P.len();
	}

	DB dis2(PT3 p1, PT3 p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y) + sqr(p1.z - p2.z);
	}

	DB dis(PT3 p1, PT3 p2) {
		return sqrt(dis2(p1, p2));
	}

	PT3 vect(PT3 p1, PT3 p2) {
		return PT3(p1.y * p2.z - p2.y * p1.z, -(p1.x * p2.z - p2.x * p1.z), p1.x * p2.y - p2.x * p1.y);
	}

	DB scal(PT3 p1, PT3 p2) {
		return p1.x * p2.x + p1.y * p2.y + p1.z * p2.z;
	}

	PT3 vect(PT3 p, PT3 p1, PT3 p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT3 p, PT3 p1, PT3 p2) {
		return scal(p1 - p, p2 - p);
	}
	//get norm of vector a
	PT3 normalize(PT3 a) {
		return a / sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
	}
	//get norm of virtically with plane abc.
	PT3 norm(PT3 a, PT3 b, PT3 c) {
		return normalize(vect(b - a, c - a)) ;
	}

	// Get Equation
	void GetEquation(PT3 A, PT3 B, PT3 C, DB &a, DB &b, DB &c, DB &d) {
		PT3 DIR = vect(B - A, C - A);
		a = DIR.x, b = DIR.y, c = DIR.z;
		d = - a * A.x - b * A.y - c * A.z;
	}

	DB GetValue(DB a, DB b, DB c, DB d, PT3 A) {
		return a * A.x + b * A.y + c * A.z + d;
	}

	// rotating points p* on plane abc to plane oxy;
	void rotate(PT3 *p, PT3 *q, int n, PT3 a, PT3 b, PT3 c) {
		PT3 pole = norm(a, b, c) ;
		PT3 polex;
		if (pole.x != 0 || pole.y != 0) polex = normalize(PT3(-pole.y, pole.x, 0));
		else polex = normalize(PT3(0, -pole.z, pole.y));
		PT3 poley = normalize(vect(pole, polex));
		DB hiv = scal(pole, p[0]);
		DB lov = hiv;
		for (int i = 0; i < n; i ++) {
			DB v = scal(pole, p[i]);
			hiv = max(v, hiv);
			lov = min(v, lov);
			DB x = scal(polex, p[i]);
			DB y = scal(poley, p[i]);
			DB z = scal(pole, p[i]);
			q[i] = PT3(x, y, z);
		}
	}

	DB disToPlane(PT3 p, DB a, DB b, DB c, DB d) {
		return abs(a * p.x + b * p.y + c * p.z + d) / sqrt(sqr(a) + sqr(b) + sqr(c));
	}

	// Projecting Point To Plane
	PT3 project(PT3 a, PT3 b, PT3 c, PT3 d) {
		PT3 tp = vect(b, c, d);
		return a - (tp * scal(tp, a - b) / scal(tp, tp));
	}

	void make_plane(PT3 p, PT3 p1, PT3 p2, DB& a, DB& b, DB& c, DB& d) {
		PT3 q = vect(p, p1, p2);
		a = q.x, b = q.y, c = q.z;
		d = -(a * p.x + b * p.y + c * p.z);
	}

	// Relation between Plane abc and Segment de
	int INTERSECT(PT3 a, PT3 b, PT3 c, PT3 d, PT3 e, PT3 &res) {
		/*
		Relation between Plain abc and Segment de...
		return 0: Pass by each other.
		return 1: Parallel but not contained.
		return 2: Intersect.
		return 3: Segment is contained on the plain.
		*/
		DB A, B, C, D;
		GetEquation(a, b, c, A, B, C, D);
		DB t1 = GetValue(A, B, C, D, d);
		DB t2 = GetValue(A, B, C, D, e);
		if (t1 > t2) swap(t1, t2), swap(d, e);
		if (fabs(t1) < EPS && fabs(t2) < EPS) {
			res = d;
			return 3;
		}
		if (fabs(t1) < EPS) {
			res = d;
			return 2;
		}
		if (fabs(t2) < EPS) {
			res = e;
			return 0;
		}
		if ((t1 > 0 && t2 > 0) || (t1 < 0 && t2 < 0)) {
			if (fabs(t1 - t2) < EPS) return 1;
			return 0;
		}
		DB Ratio = t1 / (t1 - t2);
		res = d + ((e - d) * Ratio);
		return 2;
	}
};
using namespace G3;

namespace G2{
	struct PT {
		DB x, y;

		PT() {}
		PT(DB x, DB y) : x(x), y(y) {}
	};

	bool operator<(const PT& p1, const PT& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		return p1.y + EPS < p2.y;
	}

	bool operator==(const PT& p1, const PT& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS;
	}

	PT operator+(PT p1, PT p2) {
		return PT(p1.x + p2.x, p1.y + p2.y);
	}

	PT operator-(PT p1, PT p2) {
		return PT(p1.x - p2.x, p1.y - p2.y);
	}

	PT operator*(PT p, DB c) {
		return PT(p.x * c, p.y * c);
	}

	PT operator/(PT p, DB c) {
		return PT(p.x / c, p.y / c);
	}

	DB dis(PT p) {
		return sqrt(sqr(p.x) + sqr(p.y));
	}

	DB dis2(PT p) {
		return sqr(p.x) + sqr(p.y);
	}

	PT rot(PT p, DB t) {
		return PT(p.x * cos(t) - p.y * sin(t), p.x * sin(t) + p.y * cos(t));
	}

	PT polar(PT p, DB r, DB t) {
		return PT(p.x + r * cos(t), p.y + r * sin(t));
	}

	DB dis2(PT p1, PT p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y);
	}

	DB dis(PT p1, PT p2) {
		return sqrt(dis2(p1, p2));
	}

	DB vect(PT p1, PT p2) {
		return p1.x * p2.y - p2.x * p1.y;
	}

	DB scal(PT p1, PT p2) {
		return p1.x * p2.x + p1.y * p2.y;
	}

	DB vect(PT p, PT p1, PT p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT p, PT p1, PT p2) {
		return scal(p1 - p, p2 - p);
	}

	bool onLine(PT p, PT p1, PT p2) {
		return fabs(vect(p1 - p, p2 - p)) < EPS;
	}

	bool onSeg(PT p, PT p1, PT p2) {
		if (!onLine(p, p1, p2)) return 0;
		return (p1.x - p.x) * (p2.x - p.x) < EPS && (p1.y - p.y) * (p2.y - p.y) < EPS;
	}

	PT projection(PT a, PT b, PT p) {
		return a + (a - b) * scal(p - a, a - b) / dis2(a - b);
	}

	int posLineLine(PT p1, PT p2, PT p3, PT p4, PT& p) {
		DB s1 = vect(p1, p2, p3), s2 = vect(p1, p2, p4);
		if (fabs(s1 - s2) < EPS) {
			if (fabs(s1) < EPS) return 2;
			return 0;
		}
		p = p3 + (p4 - p3) * s1 / (s1 - s2);
		return 1;
	}
};
using namespace G2;

const int N = 110000;
PT3 P[N], Q[N], _P[N], _Q[N];
PT p[N];

int main() {
//	freopen("in.txt", "r", stdin);
	int n, m; cin >> n;
	for (int i = 0; i < n; i++) P[i].in();
	cin >> m;
	for (int i = 0; i < m; i++) Q[i].in();
	rotate(P, _P, n, P[0], P[1], P[2]);
	rotate(Q, _Q, m, P[0], P[1], P[2]);
	for (int i = 0; i < n; i++) P[i] = _P[i], p[i] = PT(P[i].x, P[i].y);
	for (int i = 0; i < m; i++) Q[i] = _Q[i];
	int flg = 0;
	vector<PT> vec;
	for (int i = 0; i < m; i++) {
		PT3 res;
		if (INTERSECT(P[0], P[1], P[2], Q[i], Q[(i + 1) % m], res) == 2) vec.push_back(PT(res.x, res.y));
	}
	if (!vec.size() || flg) return puts("NO"), 0;
	assert(vec.size() % 2 == 0);
	sort(vec.begin(), vec.end());
	PT A = vec[0], B = vec.back();
	DB l = dis(A, B);
	if (fabs(l) < EPS) return puts("NO"), 0;
	vector<DB> vd;
	vector<pair<DB, int>> vp;
	for (auto &t : vec) vd.push_back(dis(A, t) / l);
	for (int i = 0; i < n; i++) {
		PT res;
		PT p1 = p[i], p2 = p[(i + 1) % n];
		int ret = posLineLine(p1, p2, A, B, res);
		if (ret == 1 && onSeg(res, p1, p2)) {
			DB d = dis(res, A) / l;
			if (onSeg(A, res, B)) d *= -1;
			if (vect(p1, A, B) < EPS && vect(p2, A, B) > EPS) vp.emplace_back(d, 1);
			if (vect(p1, A, B) > EPS && vect(p2, A, B) < EPS) vp.emplace_back(d, -1);
		}
	}
	sort(vp.begin(), vp.end());
	assert(vp.size() % 2 == 0);
	int vn = 0, cnt = 0;
	for (int i = 0; i < vd.size(); i += 2) {
		DB from = vd[i], to = vd[i + 1];
		while (vn < vp.size() && vp[vn].first < from) vn++;
		while (vn < vp.size() && vp[vn].first < to) cnt += vp[vn].second, vn++;
	}
	cnt ? puts("YES") : puts("NO");
}


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

typedef long double DB;
const DB PI = acos(DB(-1));
const DB INF = 1e10;
const DB EPS = 1e-8;

inline DB sqr(DB x) {
	return x * x;
}

namespace G3{
	struct PT3 {
		DB x, y, z;

		PT3() {}
		PT3(DB x, DB y, DB z) : x(x), y(y), z(z) {}

		void in() {
			cin >> x >> y >> z;
		}
		DB len() {
			return sqrt(sqr(x) + sqr(y) + sqr(z));
		}
	};

	bool operator<(const PT3& p1, const PT3& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		if (fabs(p1.y - p2.y) > EPS) return p1.y < p2.y;
		return p1.z + EPS < p2.z;
	}

	bool operator==(const PT3& p1, const PT3& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS && fabs(p1.z - p2.z) < EPS;
	}

	PT3 operator-(PT3 p) {
		return PT3(-p.x, -p.y, -p.z);
	}

	PT3 operator+(PT3 p1, PT3 p2) {
		return PT3(p1.x + p2.x, p1.y + p2.y, p1.z + p2.z);
	}

	PT3 operator-(PT3 p1, PT3 p2) {
		return PT3(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z);
	}

	PT3 operator*(PT3 p, DB c) {
		return PT3(p.x * c, p.y * c, p.z * c);
	}

	PT3 operator/(PT3 p, DB c) {
		return PT3(p.x / c, p.y / c, p.z / c);
	}

	DB dist(PT3 P) {
		return P.len();
	}

	DB dis2(PT3 p1, PT3 p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y) + sqr(p1.z - p2.z);
	}

	DB dis(PT3 p1, PT3 p2) {
		return sqrt(dis2(p1, p2));
	}

	PT3 vect(PT3 p1, PT3 p2) {
		return PT3(p1.y * p2.z - p2.y * p1.z, -(p1.x * p2.z - p2.x * p1.z), p1.x * p2.y - p2.x * p1.y);
	}

	DB scal(PT3 p1, PT3 p2) {
		return p1.x * p2.x + p1.y * p2.y + p1.z * p2.z;
	}

	PT3 vect(PT3 p, PT3 p1, PT3 p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT3 p, PT3 p1, PT3 p2) {
		return scal(p1 - p, p2 - p);
	}
	//get norm of vector a
	PT3 normalize(PT3 a) {
		return a / sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
	}
	//get norm of virtically with plane abc.
	PT3 norm(PT3 a, PT3 b, PT3 c) {
		return normalize(vect(b - a, c - a)) ;
	}

	// Get Equation
	void GetEquation(PT3 A, PT3 B, PT3 C, DB &a, DB &b, DB &c, DB &d) {
		PT3 DIR = vect(B - A, C - A);
		a = DIR.x, b = DIR.y, c = DIR.z;
		d = - a * A.x - b * A.y - c * A.z;
	}

	DB GetValue(DB a, DB b, DB c, DB d, PT3 A) {
		return a * A.x + b * A.y + c * A.z + d;
	}

	// rotating points p* on plane abc to plane oxy;
	void rotate(PT3 *p, PT3 *q, int n, PT3 a, PT3 b, PT3 c) {
		PT3 pole = norm(a, b, c) ;
		PT3 polex;
		if (pole.x != 0 || pole.y != 0) polex = normalize(PT3(-pole.y, pole.x, 0));
		else polex = normalize(PT3(0, -pole.z, pole.y));
		PT3 poley = normalize(vect(pole, polex));
		DB hiv = scal(pole, p[0]);
		DB lov = hiv;
		for (int i = 0; i < n; i ++) {
			DB v = scal(pole, p[i]);
			hiv = max(v, hiv);
			lov = min(v, lov);
			DB x = scal(polex, p[i]);
			DB y = scal(poley, p[i]);
			DB z = scal(pole, p[i]);
			q[i] = PT3(x, y, z);
		}
	}

	DB disToPlane(PT3 p, DB a, DB b, DB c, DB d) {
		return abs(a * p.x + b * p.y + c * p.z + d) / sqrt(sqr(a) + sqr(b) + sqr(c));
	}

	// Projecting Point To Plane
	PT3 project(PT3 a, PT3 b, PT3 c, PT3 d) {
		PT3 tp = vect(b, c, d);
		return a - (tp * scal(tp, a - b) / scal(tp, tp));
	}

	void make_plane(PT3 p, PT3 p1, PT3 p2, DB& a, DB& b, DB& c, DB& d) {
		PT3 q = vect(p, p1, p2);
		a = q.x, b = q.y, c = q.z;
		d = -(a * p.x + b * p.y + c * p.z);
	}

	// Relation between Plane abc and Segment de
	int INTERSECT(PT3 a, PT3 b, PT3 c, PT3 d, PT3 e, PT3 &res) {
		/*
		Relation between Plain abc and Segment de...
		return 0: Pass by each other.
		return 1: Parallel but not contained.
		return 2: Intersect.
		return 3: Segment is contained on the plain.
		*/
		DB A, B, C, D;
		GetEquation(a, b, c, A, B, C, D);
		DB t1 = GetValue(A, B, C, D, d);
		DB t2 = GetValue(A, B, C, D, e);
		if (fabs(t1) < EPS && fabs(t2) < EPS) {
			res = d;
			return 3;
		}
		if (fabs(t1) < EPS) {
			res = d;
			return 2;
		}
		if (fabs(t2) < EPS) {
			res = e;
			return 2;
		}
		if ((t1 > 0 && t2 > 0) || (t1 < 0 && t2 < 0)) {
			if (fabs(t1 - t2) < EPS) return 1;
			return 0;
		}
		DB Ratio = t1 / (t1 - t2);
		res = d + ((e - d) * Ratio);
		return 2;
	}
};
using namespace G3;

namespace G2{
	struct PT {
		DB x, y;

		PT() {}
		PT(DB x, DB y) : x(x), y(y) {}
	};

	bool operator<(const PT& p1, const PT& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		return p1.y + EPS < p2.y;
	}

	bool operator==(const PT& p1, const PT& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS;
	}

	PT operator+(PT p1, PT p2) {
		return PT(p1.x + p2.x, p1.y + p2.y);
	}

	PT operator-(PT p1, PT p2) {
		return PT(p1.x - p2.x, p1.y - p2.y);
	}

	PT operator*(PT p, DB c) {
		return PT(p.x * c, p.y * c);
	}

	PT operator/(PT p, DB c) {
		return PT(p.x / c, p.y / c);
	}

	DB dis(PT p) {
		return sqrt(sqr(p.x) + sqr(p.y));
	}

	DB dis2(PT p) {
		return sqr(p.x) + sqr(p.y);
	}

	PT rot(PT p, DB t) {
		return PT(p.x * cos(t) - p.y * sin(t), p.x * sin(t) + p.y * cos(t));
	}

	PT polar(PT p, DB r, DB t) {
		return PT(p.x + r * cos(t), p.y + r * sin(t));
	}

	DB dis2(PT p1, PT p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y);
	}

	DB dis(PT p1, PT p2) {
		return sqrt(dis2(p1, p2));
	}

	DB vect(PT p1, PT p2) {
		return p1.x * p2.y - p2.x * p1.y;
	}

	DB scal(PT p1, PT p2) {
		return p1.x * p2.x + p1.y * p2.y;
	}

	DB vect(PT p, PT p1, PT p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT p, PT p1, PT p2) {
		return scal(p1 - p, p2 - p);
	}

	bool onLine(PT p, PT p1, PT p2) {
		return fabs(vect(p1 - p, p2 - p)) < EPS;
	}

	bool onSeg(PT p, PT p1, PT p2) {
		if (!onLine(p, p1, p2)) return 0;
		return (p1.x - p.x) * (p2.x - p.x) < EPS && (p1.y - p.y) * (p2.y - p.y) < EPS;
	}

	PT projection(PT a, PT b, PT p) {
		return a + (a - b) * scal(p - a, a - b) / dis2(a - b);
	}

	int posLineLine(PT p1, PT p2, PT p3, PT p4, PT& p) {
		DB s1 = vect(p1, p2, p3), s2 = vect(p1, p2, p4);
		if (fabs(s1 - s2) < EPS) {
			if (fabs(s1) < EPS) return 2;
			return 0;
		}
		p = p3 + (p4 - p3) * s1 / (s1 - s2);
		return 1;
	}
};
using namespace G2;

const int N = 110000;
PT3 P[N], Q[N], _P[N], _Q[N];
PT p[N];

int main() {
//	freopen("in.txt", "r", stdin);
	ios_base::sync_with_stdio(0);
	int n, m; cin >> n;
	for (int i = 0; i < n; i++) P[i].in();
	cin >> m;
	for (int i = 0; i < m; i++) Q[i].in();
	rotate(P, _P, n, P[0], P[1], P[2]);
	rotate(Q, _Q, m, P[0], P[1], P[2]);
	for (int i = 0; i < n; i++) P[i] = _P[i], p[i] = PT(P[i].x, P[i].y);
	for (int i = 0; i < m; i++) Q[i] = _Q[i];
	int flg = 0;
	vector<PT> vec;
	for (int i = 0; i < m; i++) {
		PT3 res;
		if (INTERSECT(P[0], P[1], P[2], Q[i], Q[(i + 1) % m], res) == 2) vec.push_back(PT(res.x, res.y));
	}
//	if (!vec.size() || flg) return puts("NO"), 0;
	if (vec.size() & 1) while (1);
	sort(vec.begin(), vec.end());
	PT A = vec[0], B = vec.back();
	DB l = dis(A, B);
	if (fabs(l) < EPS) return puts("NO"), 0;
	vector<DB> vd, vp;
	for (auto &t : vec) vd.push_back(dis(A, t) / l);
	for (int i = 0; i < n; i++) {
		PT res;
		int ret = posLineLine(p[i], p[(i + 1) % n], A, B, res);
		if (ret == 1 && onSeg(res, p[i], p[(i + 1) % n])) {
			DB d = dis(res, A) / l;
			if (onSeg(A, res, B)) d *= -1;
			vp.push_back(d);
		}
	}
	sort(vp.begin(), vp.end());
//	assert(vp.size() % 2 == 0);
	int vn = 0, cnt = 0;
	for (int i = 0; i < vp.size(); i += 2) {
		DB from = vp[i], to = vp[i + 1];
		while (vn < vd.size() && vd[vn] < from) vn++;
		while (vn < vd.size() && vd[vn] < to) vn++, cnt++;
	}
	cnt & 1 ? puts("YES") : puts("NO");
}


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

typedef double DB;
const DB PI = acos(DB(-1));
const DB INF = 1e10;
const DB EPS = 1e-8;

inline DB sqr(DB x) {
	return x * x;
}

namespace G3{
	struct PT3 {
		DB x, y, z;

		PT3() {}
		PT3(DB x, DB y, DB z) : x(x), y(y), z(z) {}

		void in() {
			cin >> x >> y >> z;
		}
		DB len() {
			return sqrt(sqr(x) + sqr(y) + sqr(z));
		}
	};

	bool operator<(const PT3& p1, const PT3& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		if (fabs(p1.y - p2.y) > EPS) return p1.y < p2.y;
		return p1.z + EPS < p2.z;
	}

	bool operator==(const PT3& p1, const PT3& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS && fabs(p1.z - p2.z) < EPS;
	}

	PT3 operator-(PT3 p) {
		return PT3(-p.x, -p.y, -p.z);
	}

	PT3 operator+(PT3 p1, PT3 p2) {
		return PT3(p1.x + p2.x, p1.y + p2.y, p1.z + p2.z);
	}

	PT3 operator-(PT3 p1, PT3 p2) {
		return PT3(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z);
	}

	PT3 operator*(PT3 p, DB c) {
		return PT3(p.x * c, p.y * c, p.z * c);
	}

	PT3 operator/(PT3 p, DB c) {
		return PT3(p.x / c, p.y / c, p.z / c);
	}

	DB dist(PT3 P) {
		return P.len();
	}

	DB dis2(PT3 p1, PT3 p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y) + sqr(p1.z - p2.z);
	}

	DB dis(PT3 p1, PT3 p2) {
		return sqrt(dis2(p1, p2));
	}

	PT3 vect(PT3 p1, PT3 p2) {
		return PT3(p1.y * p2.z - p2.y * p1.z, -(p1.x * p2.z - p2.x * p1.z), p1.x * p2.y - p2.x * p1.y);
	}

	DB scal(PT3 p1, PT3 p2) {
		return p1.x * p2.x + p1.y * p2.y + p1.z * p2.z;
	}

	PT3 vect(PT3 p, PT3 p1, PT3 p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT3 p, PT3 p1, PT3 p2) {
		return scal(p1 - p, p2 - p);
	}
	//get norm of vector a
	PT3 normalize(PT3 a) {
		return a / sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
	}
	//get norm of virtically with plane abc.
	PT3 norm(PT3 a, PT3 b, PT3 c) {
		return normalize(vect(b - a, c - a)) ;
	}

	// Get Equation
	void GetEquation(PT3 A, PT3 B, PT3 C, DB &a, DB &b, DB &c, DB &d) {
		PT3 DIR = vect(B - A, C - A);
		a = DIR.x, b = DIR.y, c = DIR.z;
		d = - a * A.x - b * A.y - c * A.z;
	}

	DB GetValue(DB a, DB b, DB c, DB d, PT3 A) {
		return a * A.x + b * A.y + c * A.z + d;
	}

	// rotating points p* on plane abc to plane oxy;
	void rotate(PT3 *p, PT3 *q, int n, PT3 a, PT3 b, PT3 c) {
		PT3 pole = norm(a, b, c) ;
		PT3 polex;
		if (pole.x != 0 || pole.y != 0) {
			polex = normalize(PT3(-pole.y, pole.x, 0)) ;
		} else {
			polex = normalize(PT3(0, -pole.z, pole.y)) ;
		}
		PT3 poley = normalize(vect(pole, polex)) ;
		DB hiv = scal(pole, p[0]);
		DB lov = hiv ;
		for (int i = 0; i < n; i ++) {
			DB v = scal(pole, p[i]) ;
			hiv = max(v, hiv);
			lov = min(v, lov);
			DB x = scal(polex, p[i]) ;
			DB y = scal(poley, p[i]) ;
			q[i] = PT3(x, y, 0);
		}
	}

	DB disToPlane(PT3 p, DB a, DB b, DB c, DB d) {
		return abs(a * p.x + b * p.y + c * p.z + d) / sqrt(sqr(a) + sqr(b) + sqr(c));
	}

	// Projecting Point To Plane
	PT3 project(PT3 a, PT3 b, PT3 c, PT3 d) {
		PT3 tp = vect(b, c, d);
		return a - (tp * scal(tp, a - b) / scal(tp, tp));
	}

	void make_plane(PT3 p, PT3 p1, PT3 p2, DB& a, DB& b, DB& c, DB& d) {
		PT3 q = vect(p, p1, p2);
		a = q.x, b = q.y, c = q.z;
		d = -(a * p.x + b * p.y + c * p.z);
	}

	// Relation between Plane abc and Segment de
	int INTERSECT(PT3 a, PT3 b, PT3 c, PT3 d, PT3 e, PT3 &res) {
		/*
		Relation between Plain abc and Segment de...
		return 0: Pass by each other.
		return 1: Parallel but not contained.
		return 2: Intersect.
		return 3: Segment is contained on the plain.
		*/
		DB A, B, C, D;
		GetEquation(a, b, c, A, B, C, D);
		DB t1 = GetValue(A, B, C, D, d);
		DB t2 = GetValue(A, B, C, D, e);
		if (fabs(t1) < EPS && fabs(t2) < EPS) {
			res = d;
			return 3;
		}
		if (fabs(t1) < EPS) {
			res = d;
			return 2;
		}
		if (fabs(t2) < EPS) {
			res = e;
			return 2;
		}
		if ((t1 > 0 && t2 > 0) || (t1 < 0 && t2 < 0)) {
			if (fabs(t1 - t2) < EPS) return 1;
			return 0;
		}
		DB Ratio = t1 / (t1 - t2);
		res = d + ((e - d) * Ratio);
		return 2;
	}
};
using namespace G3;

namespace G2{
	struct PT {
		DB x, y;

		PT() {}
		PT(DB x, DB y) : x(x), y(y) {}
	};

	bool operator<(const PT& p1, const PT& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		return p1.y + EPS < p2.y;
	}

	bool operator==(const PT& p1, const PT& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS;
	}

	PT operator+(PT p1, PT p2) {
		return PT(p1.x + p2.x, p1.y + p2.y);
	}

	PT operator-(PT p1, PT p2) {
		return PT(p1.x - p2.x, p1.y - p2.y);
	}

	PT operator*(PT p, DB c) {
		return PT(p.x * c, p.y * c);
	}

	PT operator/(PT p, DB c) {
		return PT(p.x / c, p.y / c);
	}

	DB dis(PT p) {
		return sqrt(sqr(p.x) + sqr(p.y));
	}

	DB dis2(PT p) {
		return sqr(p.x) + sqr(p.y);
	}

	PT rot(PT p, DB t) {
		return PT(p.x * cos(t) - p.y * sin(t), p.x * sin(t) + p.y * cos(t));
	}

	PT polar(PT p, DB r, DB t) {
		return PT(p.x + r * cos(t), p.y + r * sin(t));
	}

	DB dis2(PT p1, PT p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y);
	}

	DB dis(PT p1, PT p2) {
		return sqrt(dis2(p1, p2));
	}

	DB vect(PT p1, PT p2) {
		return p1.x * p2.y - p2.x * p1.y;
	}

	DB scal(PT p1, PT p2) {
		return p1.x * p2.x + p1.y * p2.y;
	}

	DB vect(PT p, PT p1, PT p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT p, PT p1, PT p2) {
		return scal(p1 - p, p2 - p);
	}

	bool onLine(PT p, PT p1, PT p2) {
		return fabs(vect(p1 - p, p2 - p)) < EPS;
	}

	bool onSeg(PT p, PT p1, PT p2) {
		if (!onLine(p, p1, p2)) return 0;
		return (p1.x - p.x) * (p2.x - p.x) < EPS && (p1.y - p.y) * (p2.y - p.y) < EPS;
	}

	PT projection(PT a, PT b, PT p) {
		return a + (a - b) * scal(p - a, a - b) / dis2(a - b);
	}

	int posLineLine(PT p1, PT p2, PT p3, PT p4, PT& p) {
		DB s1 = vect(p1, p2, p3), s2 = vect(p1, p2, p4);
		if (fabs(s1 - s2) < EPS) {
			if (fabs(s1) < EPS) return 2;
			return 0;
		}
		p = p3 + (p4 - p3) * s1 / (s1 - s2);
		return 1;
	}
};
using namespace G2;

const int N = 110000;
PT3 P[N], Q[N], _P[N], _Q[N];
PT p[N];

int main() {
//	freopen("in.txt", "r", stdin);
	ios_base::sync_with_stdio(0);
	int n, m; cin >> n;
	for (int i = 0; i < n; i++) P[i].in();
	cin >> m;
	for (int i = 0; i < m; i++) Q[i].in();
	rotate(P, _P, n, P[0], P[1], P[2]);
	rotate(Q, _Q, n, P[0], P[1], P[2]);
	for (int i = 0; i < n; i++) P[i] = _P[i], p[i] = {P[i].x, P[i].y};
	for (int i = 0; i < m; i++) Q[i] = _Q[i];
	int flg = 0;
	vector<PT> vec;
	for (int i = 0; i < m; i++) {
		PT3 res;
		int ret = INTERSECT(P[0], P[1], P[2], Q[i], Q[(i + 1) % m], res);
		if (!ret) continue;
		if (ret == 1 || ret == 3) {
			flg = 1;
			break;
		}
		vec.push_back(PT(res.x, res.y));
	}
	if (!vec.size() || flg) return puts("YES"), 0;
	assert(0);
	sort(vec.begin(), vec.end());
	assert(vec.size() % 2 == 0);
	PT A = vec[0], B = vec.back();
	DB l = dis(A, B);
	vector<DB> vd, vp;
	for (auto &t : vec) vd.push_back(dis(A, t) / l);
	for (int i = 0; i < n; i++) {
		PT res;
		int ret = posLineLine(p[i], p[(i + 1) % n], A, B, res);
		if (ret == 1) {
			DB d = dis(res, A) / l;
			if (onSeg(A, res, B)) d *= -1;
			vp.push_back(d);
		}
	}
	sort(vp.begin(), vp.end());
	assert(vp.size() % 2 == 0);
	int vn = 0, cnt = 0;
	for (int i = 0; i < vp.size(); i += 2) {
		DB from = vp[i], to = vp[i + 1];
		while (vn < vd.size() && vd[vn] < from) vn++;
		while (vn < vd.size() && vd[vn] < to) vn++, cnt++;
	}
	cnt & 1 ? puts("NO") : puts("YES");
}


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

typedef long double DB;
const DB PI = acos(DB(-1));
const DB INF = 1e10;
const DB EPS = 1e-8;

inline DB sqr(DB x) {
	return x * x;
}

namespace G3{
	struct PT3 {
		DB x, y, z;

		PT3() {}
		PT3(DB x, DB y, DB z) : x(x), y(y), z(z) {}

		void in() {
			cin >> x >> y >> z;
		}
		DB len() {
			return sqrt(sqr(x) + sqr(y) + sqr(z));
		}
	};

	bool operator<(const PT3& p1, const PT3& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		if (fabs(p1.y - p2.y) > EPS) return p1.y < p2.y;
		return p1.z + EPS < p2.z;
	}

	bool operator==(const PT3& p1, const PT3& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS && fabs(p1.z - p2.z) < EPS;
	}

	PT3 operator-(PT3 p) {
		return PT3(-p.x, -p.y, -p.z);
	}

	PT3 operator+(PT3 p1, PT3 p2) {
		return PT3(p1.x + p2.x, p1.y + p2.y, p1.z + p2.z);
	}

	PT3 operator-(PT3 p1, PT3 p2) {
		return PT3(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z);
	}

	PT3 operator*(PT3 p, DB c) {
		return PT3(p.x * c, p.y * c, p.z * c);
	}

	PT3 operator/(PT3 p, DB c) {
		return PT3(p.x / c, p.y / c, p.z / c);
	}

	DB dist(PT3 P) {
		return P.len();
	}

	DB dis2(PT3 p1, PT3 p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y) + sqr(p1.z - p2.z);
	}

	DB dis(PT3 p1, PT3 p2) {
		return sqrt(dis2(p1, p2));
	}

	PT3 vect(PT3 p1, PT3 p2) {
		return PT3(p1.y * p2.z - p2.y * p1.z, -(p1.x * p2.z - p2.x * p1.z), p1.x * p2.y - p2.x * p1.y);
	}

	DB scal(PT3 p1, PT3 p2) {
		return p1.x * p2.x + p1.y * p2.y + p1.z * p2.z;
	}

	PT3 vect(PT3 p, PT3 p1, PT3 p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT3 p, PT3 p1, PT3 p2) {
		return scal(p1 - p, p2 - p);
	}
	//get norm of vector a
	PT3 normalize(PT3 a) {
		return a / sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
	}
	//get norm of virtically with plane abc.
	PT3 norm(PT3 a, PT3 b, PT3 c) {
		return normalize(vect(b - a, c - a)) ;
	}

	// Get Equation
	void GetEquation(PT3 A, PT3 B, PT3 C, DB &a, DB &b, DB &c, DB &d) {
		PT3 DIR = vect(B - A, C - A);
		a = DIR.x, b = DIR.y, c = DIR.z;
		d = - a * A.x - b * A.y - c * A.z;
	}

	DB GetValue(DB a, DB b, DB c, DB d, PT3 A) {
		return a * A.x + b * A.y + c * A.z + d;
	}

	// rotating points p* on plane abc to plane oxy;
	void rotate(PT3 *p, PT3 *q, int n, PT3 a, PT3 b, PT3 c) {
		PT3 pole = norm(a, b, c) ;
		PT3 polex;
		if (pole.x != 0 || pole.y != 0) polex = normalize(PT3(-pole.y, pole.x, 0));
		else polex = normalize(PT3(0, -pole.z, pole.y));
		PT3 poley = normalize(vect(pole, polex));
		DB hiv = scal(pole, p[0]);
		DB lov = hiv;
		for (int i = 0; i < n; i ++) {
			DB v = scal(pole, p[i]);
			hiv = max(v, hiv);
			lov = min(v, lov);
			DB x = scal(polex, p[i]);
			DB y = scal(poley, p[i]);
			DB z = scal(pole, p[i]);
			q[i] = PT3(x, y, z);
		}
	}

	DB disToPlane(PT3 p, DB a, DB b, DB c, DB d) {
		return abs(a * p.x + b * p.y + c * p.z + d) / sqrt(sqr(a) + sqr(b) + sqr(c));
	}

	// Projecting Point To Plane
	PT3 project(PT3 a, PT3 b, PT3 c, PT3 d) {
		PT3 tp = vect(b, c, d);
		return a - (tp * scal(tp, a - b) / scal(tp, tp));
	}

	void make_plane(PT3 p, PT3 p1, PT3 p2, DB& a, DB& b, DB& c, DB& d) {
		PT3 q = vect(p, p1, p2);
		a = q.x, b = q.y, c = q.z;
		d = -(a * p.x + b * p.y + c * p.z);
	}

	// Relation between Plane abc and Segment de
	int INTERSECT(PT3 a, PT3 b, PT3 c, PT3 d, PT3 e, PT3 &res) {
		/*
		Relation between Plain abc and Segment de...
		return 0: Pass by each other.
		return 1: Parallel but not contained.
		return 2: Intersect.
		return 3: Segment is contained on the plain.
		*/
		DB A, B, C, D;
		GetEquation(a, b, c, A, B, C, D);
		DB t1 = GetValue(A, B, C, D, d);
		DB t2 = GetValue(A, B, C, D, e);
		if (t1 > t2) swap(t1, t2), swap(d, e);
		if (fabs(t1) < EPS && fabs(t2) < EPS) {
			res = d;
			return 3;
		}
		if (fabs(t1) < EPS) {
			res = d;
			return 2;
		}
		if (fabs(t2) < EPS) {
			res = e;
			return 0;
		}
		if ((t1 > 0 && t2 > 0) || (t1 < 0 && t2 < 0)) {
			if (fabs(t1 - t2) < EPS) return 1;
			return 0;
		}
		DB Ratio = t1 / (t1 - t2);
		res = d + ((e - d) * Ratio);
		return 2;
	}
};
using namespace G3;

namespace G2{
	struct PT {
		DB x, y;

		PT() {}
		PT(DB x, DB y) : x(x), y(y) {}
	};

	bool operator<(const PT& p1, const PT& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		return p1.y + EPS < p2.y;
	}

	bool operator==(const PT& p1, const PT& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS;
	}

	PT operator+(PT p1, PT p2) {
		return PT(p1.x + p2.x, p1.y + p2.y);
	}

	PT operator-(PT p1, PT p2) {
		return PT(p1.x - p2.x, p1.y - p2.y);
	}

	PT operator*(PT p, DB c) {
		return PT(p.x * c, p.y * c);
	}

	PT operator/(PT p, DB c) {
		return PT(p.x / c, p.y / c);
	}

	DB dis(PT p) {
		return sqrt(sqr(p.x) + sqr(p.y));
	}

	DB dis2(PT p) {
		return sqr(p.x) + sqr(p.y);
	}

	PT rot(PT p, DB t) {
		return PT(p.x * cos(t) - p.y * sin(t), p.x * sin(t) + p.y * cos(t));
	}

	PT polar(PT p, DB r, DB t) {
		return PT(p.x + r * cos(t), p.y + r * sin(t));
	}

	DB dis2(PT p1, PT p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y);
	}

	DB dis(PT p1, PT p2) {
		return sqrt(dis2(p1, p2));
	}

	DB vect(PT p1, PT p2) {
		return p1.x * p2.y - p2.x * p1.y;
	}

	DB scal(PT p1, PT p2) {
		return p1.x * p2.x + p1.y * p2.y;
	}

	DB vect(PT p, PT p1, PT p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT p, PT p1, PT p2) {
		return scal(p1 - p, p2 - p);
	}

	bool onLine(PT p, PT p1, PT p2) {
		return fabs(vect(p1 - p, p2 - p)) < EPS;
	}

	bool onSeg(PT p, PT p1, PT p2) {
		if (!onLine(p, p1, p2)) return 0;
		return (p1.x - p.x) * (p2.x - p.x) < EPS && (p1.y - p.y) * (p2.y - p.y) < EPS;
	}

	PT projection(PT a, PT b, PT p) {
		return a + (a - b) * scal(p - a, a - b) / dis2(a - b);
	}

	int posLineLine(PT p1, PT p2, PT p3, PT p4, PT& p) {
		DB s1 = vect(p1, p2, p3), s2 = vect(p1, p2, p4);
		if (fabs(s1 - s2) < EPS) {
			if (fabs(s1) < EPS) return 2;
			return 0;
		}
		p = p3 + (p4 - p3) * s1 / (s1 - s2);
		return 1;
	}
};
using namespace G2;

const int N = 110000;
PT3 P[N], Q[N], _P[N], _Q[N];
PT p[N];

int main() {
//	freopen("in.txt", "r", stdin);
	ios_base::sync_with_stdio(0);
	int n, m; cin >> n;
	for (int i = 0; i < n; i++) P[i].in();
	cin >> m;
	for (int i = 0; i < m; i++) Q[i].in();
	rotate(P, _P, n, P[0], P[1], P[2]);
	rotate(Q, _Q, m, P[0], P[1], P[2]);
	for (int i = 0; i < n; i++) P[i] = _P[i], p[i] = PT(P[i].x, P[i].y);
	for (int i = 0; i < m; i++) Q[i] = _Q[i];
	int flg = 0;
	vector<PT> vec;
	for (int i = 0; i < m; i++) {
		PT3 res;
		if (INTERSECT(P[0], P[1], P[2], Q[i], Q[(i + 1) % m], res) == 2) vec.push_back(PT(res.x, res.y));
	}
	if (!vec.size() || flg) return puts("NO"), 0;
	if (vec.size() & 1) while (1);
	sort(vec.begin(), vec.end());
	PT A = vec[0], B = vec.back();
	DB l = dis(A, B);
	if (fabs(l) < EPS) return puts("NO"), 0;
	vector<DB> vd;
	vector<pair<DB, int>> vp;
	for (auto &t : vec) vd.push_back(dis(A, t) / l);
	for (int i = 0; i < n; i++) {
		PT res;
		int ret = posLineLine(p[i], p[(i + 1) % n], A, B, res);
		if (ret == 1 && onSeg(res, p[i], p[(i + 1) % n]) && dis(res, p[i]) > EPS) {
			int dir = -1;
			if (vect(p[i], A, B) < 0) dir = 1;
			DB d = dis(res, A) / l;
			if (onSeg(A, res, B)) d *= -1;
			vp.emplace_back(d, dir);
		}
	}
	sort(vp.begin(), vp.end());
	assert(vp.size() % 2 == 0);
	int vn = 0, cnt = 0;
	for (int i = 0; i < vd.size(); i += 2) {
		DB from = vd[i], to = vd[i + 1];
		while (vn < vp.size() && vp[vn].first < from) vn++;
		while (vn < vp.size() && vp[vn].first < to) cnt += vp[vn].second, vn++;
	}
	cnt & 1 ? puts("YES") : puts("NO");
}


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

typedef double DB;
const DB PI = acos(DB(-1));
const DB INF = 1e10;
const DB EPS = 1e-8;

inline DB sqr(DB x) {
	return x * x;
}

namespace G3{
	struct PT3 {
		DB x, y, z;

		PT3() {}
		PT3(DB x, DB y, DB z) : x(x), y(y), z(z) {}

		void in() {
			cin >> x >> y >> z;
		}
		DB len() {
			return sqrt(sqr(x) + sqr(y) + sqr(z));
		}
	};

	bool operator<(const PT3& p1, const PT3& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		if (fabs(p1.y - p2.y) > EPS) return p1.y < p2.y;
		return p1.z + EPS < p2.z;
	}

	bool operator==(const PT3& p1, const PT3& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS && fabs(p1.z - p2.z) < EPS;
	}

	PT3 operator-(PT3 p) {
		return PT3(-p.x, -p.y, -p.z);
	}

	PT3 operator+(PT3 p1, PT3 p2) {
		return PT3(p1.x + p2.x, p1.y + p2.y, p1.z + p2.z);
	}

	PT3 operator-(PT3 p1, PT3 p2) {
		return PT3(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z);
	}

	PT3 operator*(PT3 p, DB c) {
		return PT3(p.x * c, p.y * c, p.z * c);
	}

	PT3 operator/(PT3 p, DB c) {
		return PT3(p.x / c, p.y / c, p.z / c);
	}

	DB dist(PT3 P) {
		return P.len();
	}

	DB dis2(PT3 p1, PT3 p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y) + sqr(p1.z - p2.z);
	}

	DB dis(PT3 p1, PT3 p2) {
		return sqrt(dis2(p1, p2));
	}

	PT3 vect(PT3 p1, PT3 p2) {
		return PT3(p1.y * p2.z - p2.y * p1.z, -(p1.x * p2.z - p2.x * p1.z), p1.x * p2.y - p2.x * p1.y);
	}

	DB scal(PT3 p1, PT3 p2) {
		return p1.x * p2.x + p1.y * p2.y + p1.z * p2.z;
	}

	PT3 vect(PT3 p, PT3 p1, PT3 p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT3 p, PT3 p1, PT3 p2) {
		return scal(p1 - p, p2 - p);
	}
	//get norm of vector a
	PT3 normalize(PT3 a) {
		return a / sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
	}
	//get norm of virtically with plane abc.
	PT3 norm(PT3 a, PT3 b, PT3 c) {
		return normalize(vect(b - a, c - a)) ;
	}

	// Get Equation
	void GetEquation(PT3 A, PT3 B, PT3 C, DB &a, DB &b, DB &c, DB &d) {
		PT3 DIR = vect(B - A, C - A);
		a = DIR.x, b = DIR.y, c = DIR.z;
		d = - a * A.x - b * A.y - c * A.z;
	}

	DB GetValue(DB a, DB b, DB c, DB d, PT3 A) {
		return a * A.x + b * A.y + c * A.z + d;
	}

	// rotating points p* on plane abc to plane oxy;
	void rotate(PT3 *p, PT3 *q, int n, PT3 a, PT3 b, PT3 c) {
		PT3 pole = norm(a, b, c) ;
		PT3 polex;
		if (pole.x != 0 || pole.y != 0) {
			polex = normalize(PT3(-pole.y, pole.x, 0)) ;
		} else {
			polex = normalize(PT3(0, -pole.z, pole.y)) ;
		}
		PT3 poley = normalize(vect(pole, polex)) ;
		DB hiv = scal(pole, p[0]);
		DB lov = hiv ;
		for (int i = 0; i < n; i ++) {
			DB v = scal(pole, p[i]) ;
			hiv = max(v, hiv);
			lov = min(v, lov);
			DB x = scal(polex, p[i]) ;
			DB y = scal(poley, p[i]) ;
			q[i] = PT3(x, y, 0);
		}
	}

	DB disToPlane(PT3 p, DB a, DB b, DB c, DB d) {
		return abs(a * p.x + b * p.y + c * p.z + d) / sqrt(sqr(a) + sqr(b) + sqr(c));
	}

	// Projecting Point To Plane
	PT3 project(PT3 a, PT3 b, PT3 c, PT3 d) {
		PT3 tp = vect(b, c, d);
		return a - (tp * scal(tp, a - b) / scal(tp, tp));
	}

	void make_plane(PT3 p, PT3 p1, PT3 p2, DB& a, DB& b, DB& c, DB& d) {
		PT3 q = vect(p, p1, p2);
		a = q.x, b = q.y, c = q.z;
		d = -(a * p.x + b * p.y + c * p.z);
	}

	// Relation between Plane abc and Segment de
	int INTERSECT(PT3 a, PT3 b, PT3 c, PT3 d, PT3 e, PT3 &res) {
		/*
		Relation between Plain abc and Segment de...
		return 0: Pass by each other.
		return 1: Parallel but not contained.
		return 2: Intersect.
		return 3: Segment is contained on the plain.
		*/
		DB A, B, C, D;
		GetEquation(a, b, c, A, B, C, D);
		DB t1 = GetValue(A, B, C, D, d);
		DB t2 = GetValue(A, B, C, D, e);
		if (fabs(t1) < EPS && fabs(t2) < EPS) {
			res = d;
			return 3;
		}
		if (fabs(t1) < EPS) {
			res = d;
			return 2;
		}
		if (fabs(t2) < EPS) {
			res = e;
			return 2;
		}
		if ((t1 > 0 && t2 > 0) || (t1 < 0 && t2 < 0)) {
			if (fabs(t1 - t2) < EPS) return 1;
			return 0;
		}
		DB Ratio = t1 / (t1 - t2);
		res = d + ((e - d) * Ratio);
		return 2;
	}
};
using namespace G3;

namespace G2{
	struct PT {
		DB x, y;

		PT() {}
		PT(DB x, DB y) : x(x), y(y) {}
	};

	bool operator<(const PT& p1, const PT& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		return p1.y + EPS < p2.y;
	}

	bool operator==(const PT& p1, const PT& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS;
	}

	PT operator+(PT p1, PT p2) {
		return PT(p1.x + p2.x, p1.y + p2.y);
	}

	PT operator-(PT p1, PT p2) {
		return PT(p1.x - p2.x, p1.y - p2.y);
	}

	PT operator*(PT p, DB c) {
		return PT(p.x * c, p.y * c);
	}

	PT operator/(PT p, DB c) {
		return PT(p.x / c, p.y / c);
	}

	DB dis(PT p) {
		return sqrt(sqr(p.x) + sqr(p.y));
	}

	DB dis2(PT p) {
		return sqr(p.x) + sqr(p.y);
	}

	PT rot(PT p, DB t) {
		return PT(p.x * cos(t) - p.y * sin(t), p.x * sin(t) + p.y * cos(t));
	}

	PT polar(PT p, DB r, DB t) {
		return PT(p.x + r * cos(t), p.y + r * sin(t));
	}

	DB dis2(PT p1, PT p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y);
	}

	DB dis(PT p1, PT p2) {
		return sqrt(dis2(p1, p2));
	}

	DB vect(PT p1, PT p2) {
		return p1.x * p2.y - p2.x * p1.y;
	}

	DB scal(PT p1, PT p2) {
		return p1.x * p2.x + p1.y * p2.y;
	}

	DB vect(PT p, PT p1, PT p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT p, PT p1, PT p2) {
		return scal(p1 - p, p2 - p);
	}

	bool onLine(PT p, PT p1, PT p2) {
		return fabs(vect(p1 - p, p2 - p)) < EPS;
	}

	bool onSeg(PT p, PT p1, PT p2) {
		if (!onLine(p, p1, p2)) return 0;
		return (p1.x - p.x) * (p2.x - p.x) < EPS && (p1.y - p.y) * (p2.y - p.y) < EPS;
	}

	PT projection(PT a, PT b, PT p) {
		return a + (a - b) * scal(p - a, a - b) / dis2(a - b);
	}

	int posLineLine(PT p1, PT p2, PT p3, PT p4, PT& p) {
		DB s1 = vect(p1, p2, p3), s2 = vect(p1, p2, p4);
		if (fabs(s1 - s2) < EPS) {
			if (fabs(s1) < EPS) return 2;
			return 0;
		}
		p = p3 + (p4 - p3) * s1 / (s1 - s2);
		return 1;
	}
};
using namespace G2;

const int N = 110000;
PT3 P[N], Q[N], _P[N], _Q[N];
PT p[N];

int main() {
//	freopen("in.txt", "r", stdin);
	ios_base::sync_with_stdio(0);
	int n, m; cin >> n;
	for (int i = 0; i < n; i++) P[i].in();
	cin >> m;
	for (int i = 0; i < m; i++) Q[i].in();
	rotate(P, _P, n, P[0], P[1], P[2]);
	rotate(Q, _Q, n, P[0], P[1], P[2]);
	for (int i = 0; i < n; i++) P[i] = _P[i], p[i] = {P[i].x, P[i].y};
	for (int i = 0; i < m; i++) Q[i] = _Q[i];
	int flg = 0;
	vector<PT> vec;
	for (int i = 0; i < m; i++) {
		PT3 res;
		int ret = INTERSECT(P[0], P[1], P[2], Q[i], Q[(i + 1) % m], res);
		if (!ret) continue;
		if (ret == 1 || ret == 3) {
			flg = 1;
			break;
		}
		vec.push_back(PT(res.x, res.y));
	}
	if (!vec.size() || flg) return puts("YES"), 0;
	sort(vec.begin(), vec.end());
	assert(vec.size() % 2 == 0);
	PT A = vec[0], B = vec.back();
	DB l = dis(A, B);
	vector<DB> vd, vp;
	for (auto &t : vec) vd.push_back(dis(A, t) / l);
	for (int i = 0; i < n; i++) {
		PT res;
		int ret = posLineLine(p[i], p[(i + 1) % n], A, B, res);
		if (ret == 1) {
			DB d = dis(res, A) / l;
			if (onSeg(A, res, B)) d *= -1;
			vp.push_back(d);
		}
	}
	sort(vp.begin(), vp.end());
	assert(vp.size() % 2 == 0);
	int vn = 0, cnt = 0;
	for (int i = 0; i < vp.size(); i += 2) {
		DB from = vp[i], to = vp[i + 1];
		while (vn < vd.size() && vd[vn] < from) vn++;
		while (vn < vd.size() && vd[vn] < to) vn++, cnt++;
	}
	cnt & 1 ? puts("NO"), assert(0) : puts("YES");
}


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

typedef double DB;
const DB PI = acos(DB(-1));
const DB INF = 1e10;
const DB EPS = 1e-8;

inline DB sqr(DB x) {
	return x * x;
}

namespace G3{
	struct PT3 {
		DB x, y, z;

		PT3() {}
		PT3(DB x, DB y, DB z) : x(x), y(y), z(z) {}

		void in() {
			cin >> x >> y >> z;
		}
		DB len() {
			return sqrt(sqr(x) + sqr(y) + sqr(z));
		}
	};

	bool operator<(const PT3& p1, const PT3& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		if (fabs(p1.y - p2.y) > EPS) return p1.y < p2.y;
		return p1.z + EPS < p2.z;
	}

	bool operator==(const PT3& p1, const PT3& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS && fabs(p1.z - p2.z) < EPS;
	}

	PT3 operator-(PT3 p) {
		return PT3(-p.x, -p.y, -p.z);
	}

	PT3 operator+(PT3 p1, PT3 p2) {
		return PT3(p1.x + p2.x, p1.y + p2.y, p1.z + p2.z);
	}

	PT3 operator-(PT3 p1, PT3 p2) {
		return PT3(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z);
	}

	PT3 operator*(PT3 p, DB c) {
		return PT3(p.x * c, p.y * c, p.z * c);
	}

	PT3 operator/(PT3 p, DB c) {
		return PT3(p.x / c, p.y / c, p.z / c);
	}

	DB dist(PT3 P) {
		return P.len();
	}

	DB dis2(PT3 p1, PT3 p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y) + sqr(p1.z - p2.z);
	}

	DB dis(PT3 p1, PT3 p2) {
		return sqrt(dis2(p1, p2));
	}

	PT3 vect(PT3 p1, PT3 p2) {
		return PT3(p1.y * p2.z - p2.y * p1.z, -(p1.x * p2.z - p2.x * p1.z), p1.x * p2.y - p2.x * p1.y);
	}

	DB scal(PT3 p1, PT3 p2) {
		return p1.x * p2.x + p1.y * p2.y + p1.z * p2.z;
	}

	PT3 vect(PT3 p, PT3 p1, PT3 p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT3 p, PT3 p1, PT3 p2) {
		return scal(p1 - p, p2 - p);
	}
	//get norm of vector a
	PT3 normalize(PT3 a) {
		return a / sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
	}
	//get norm of virtically with plane abc.
	PT3 norm(PT3 a, PT3 b, PT3 c) {
		return normalize(vect(b - a, c - a)) ;
	}

	// Get Equation
	void GetEquation(PT3 A, PT3 B, PT3 C, DB &a, DB &b, DB &c, DB &d) {
		PT3 DIR = vect(B - A, C - A);
		a = DIR.x, b = DIR.y, c = DIR.z;
		d = - a * A.x - b * A.y - c * A.z;
	}

	DB GetValue(DB a, DB b, DB c, DB d, PT3 A) {
		return a * A.x + b * A.y + c * A.z + d;
	}

	// rotating points p* on plane abc to plane oxy;
	void rotate(PT3 *p, PT3 *q, int n, PT3 a, PT3 b, PT3 c) {
		PT3 pole = norm(a, b, c) ;
		PT3 polex;
		if (pole.x != 0 || pole.y != 0) {
			polex = normalize(PT3(-pole.y, pole.x, 0)) ;
		} else {
			polex = normalize(PT3(0, -pole.z, pole.y)) ;
		}
		PT3 poley = normalize(vect(pole, polex)) ;
		DB hiv = scal(pole, p[0]);
		DB lov = hiv ;
		for (int i = 0; i < n; i ++) {
			DB v = scal(pole, p[i]) ;
			hiv = max(v, hiv);
			lov = min(v, lov);
			DB x = scal(polex, p[i]) ;
			DB y = scal(poley, p[i]) ;
			q[i] = PT3(x, y, 0);
		}
	}

	DB disToPlane(PT3 p, DB a, DB b, DB c, DB d) {
		return abs(a * p.x + b * p.y + c * p.z + d) / sqrt(sqr(a) + sqr(b) + sqr(c));
	}

	// Projecting Point To Plane
	PT3 project(PT3 a, PT3 b, PT3 c, PT3 d) {
		PT3 tp = vect(b, c, d);
		return a - (tp * scal(tp, a - b) / scal(tp, tp));
	}

	void make_plane(PT3 p, PT3 p1, PT3 p2, DB& a, DB& b, DB& c, DB& d) {
		PT3 q = vect(p, p1, p2);
		a = q.x, b = q.y, c = q.z;
		d = -(a * p.x + b * p.y + c * p.z);
	}

	// Relation between Plane abc and Segment de
	int INTERSECT(PT3 a, PT3 b, PT3 c, PT3 d, PT3 e, PT3 &res) {
		/*
		Relation between Plain abc and Segment de...
		return 0: Pass by each other.
		return 1: Parallel but not contained.
		return 2: Intersect.
		return 3: Segment is contained on the plain.
		*/
		DB A, B, C, D;
		GetEquation(a, b, c, A, B, C, D);
		DB t1 = GetValue(A, B, C, D, d);
		DB t2 = GetValue(A, B, C, D, e);
		if (fabs(t1) < EPS && fabs(t2) < EPS) {
			res = d;
			return 3;
		}
		if (fabs(t1) < EPS) {
			res = d;
			return 2;
		}
		if (fabs(t2) < EPS) {
			res = e;
			return 2;
		}
		if ((t1 > 0 && t2 > 0) || (t1 < 0 && t2 < 0)) {
			if (fabs(t1 - t2) < EPS) return 1;
			return 0;
		}
		DB Ratio = t1 / (t1 - t2);
		res = d + ((e - d) * Ratio);
		return 2;
	}
};
using namespace G3;

namespace G2{
	struct PT {
		DB x, y;

		PT() {}
		PT(DB x, DB y) : x(x), y(y) {}
	};

	bool operator<(const PT& p1, const PT& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		return p1.y + EPS < p2.y;
	}

	bool operator==(const PT& p1, const PT& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS;
	}

	PT operator+(PT p1, PT p2) {
		return PT(p1.x + p2.x, p1.y + p2.y);
	}

	PT operator-(PT p1, PT p2) {
		return PT(p1.x - p2.x, p1.y - p2.y);
	}

	PT operator*(PT p, DB c) {
		return PT(p.x * c, p.y * c);
	}

	PT operator/(PT p, DB c) {
		return PT(p.x / c, p.y / c);
	}

	DB dis(PT p) {
		return sqrt(sqr(p.x) + sqr(p.y));
	}

	DB dis2(PT p) {
		return sqr(p.x) + sqr(p.y);
	}

	PT rot(PT p, DB t) {
		return PT(p.x * cos(t) - p.y * sin(t), p.x * sin(t) + p.y * cos(t));
	}

	PT polar(PT p, DB r, DB t) {
		return PT(p.x + r * cos(t), p.y + r * sin(t));
	}

	DB dis2(PT p1, PT p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y);
	}

	DB dis(PT p1, PT p2) {
		return sqrt(dis2(p1, p2));
	}

	DB vect(PT p1, PT p2) {
		return p1.x * p2.y - p2.x * p1.y;
	}

	DB scal(PT p1, PT p2) {
		return p1.x * p2.x + p1.y * p2.y;
	}

	DB vect(PT p, PT p1, PT p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT p, PT p1, PT p2) {
		return scal(p1 - p, p2 - p);
	}

	bool onLine(PT p, PT p1, PT p2) {
		return fabs(vect(p1 - p, p2 - p)) < EPS;
	}

	bool onSeg(PT p, PT p1, PT p2) {
		if (!onLine(p, p1, p2)) return 0;
		return (p1.x - p.x) * (p2.x - p.x) < EPS && (p1.y - p.y) * (p2.y - p.y) < EPS;
	}

	PT projection(PT a, PT b, PT p) {
		return a + (a - b) * scal(p - a, a - b) / dis2(a - b);
	}

	int posLineLine(PT p1, PT p2, PT p3, PT p4, PT& p) {
		DB s1 = vect(p1, p2, p3), s2 = vect(p1, p2, p4);
		if (fabs(s1 - s2) < EPS) {
			if (fabs(s1) < EPS) return 2;
			return 0;
		}
		p = p3 + (p4 - p3) * s1 / (s1 - s2);
		return 1;
	}
};
using namespace G2;

const int N = 110000;
PT3 P[N], Q[N], _P[N], _Q[N];
PT p[N];

int main() {
//	freopen("in.txt", "r", stdin);
	ios_base::sync_with_stdio(0);
	int n, m; cin >> n;
	for (int i = 0; i < n; i++) P[i].in();
	cin >> m;
	for (int i = 0; i < m; i++) Q[i].in();
	rotate(P, _P, n, P[0], P[1], P[2]);
	rotate(Q, _Q, m, P[0], P[1], P[2]);
	for (int i = 0; i < n; i++) P[i] = _P[i], p[i] = {P[i].x, P[i].y};
	for (int i = 0; i < m; i++) Q[i] = _Q[i];
	int flg = 0;
	vector<PT> vec;
	for (int i = 0; i < m; i++) {
		PT3 res;
		int ret = INTERSECT(P[0], P[1], P[2], Q[i], Q[(i + 1) % m], res);
		if (!ret) continue;
		if (ret == 1 || ret == 3) {
			flg = 1;
			break;
		}
		vec.push_back(PT(res.x, res.y));
	}
	if (!vec.size() || flg) return puts("YES"), 0;
	assert(0);
	sort(vec.begin(), vec.end());
	assert(vec.size() % 2 == 0);
	PT A = vec[0], B = vec.back();
	DB l = dis(A, B);
	vector<DB> vd, vp;
	for (auto &t : vec) vd.push_back(dis(A, t) / l);
	for (int i = 0; i < n; i++) {
		PT res;
		int ret = posLineLine(p[i], p[(i + 1) % n], A, B, res);
		if (ret == 1) {
			DB d = dis(res, A) / l;
			if (onSeg(A, res, B)) d *= -1;
			vp.push_back(d);
		}
	}
	sort(vp.begin(), vp.end());
	assert(vp.size() % 2 == 0);
	int vn = 0, cnt = 0;
	for (int i = 0; i < vp.size(); i += 2) {
		DB from = vp[i], to = vp[i + 1];
		while (vn < vd.size() && vd[vn] < from) vn++;
		while (vn < vd.size() && vd[vn] < to) vn++, cnt++;
	}
	cnt & 1 ? puts("NO") : puts("YES");
}


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

typedef long double DB;
const DB PI = acos(DB(-1));
const DB INF = 1e10;
const DB EPS = 1e-8;

inline DB sqr(DB x) {
	return x * x;
}

namespace G3{
	struct PT3 {
		DB x, y, z;

		PT3() {}
		PT3(DB x, DB y, DB z) : x(x), y(y), z(z) {}

		void in() {
			cin >> x >> y >> z;
		}
		DB len() {
			return sqrt(sqr(x) + sqr(y) + sqr(z));
		}
	};

	bool operator<(const PT3& p1, const PT3& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		if (fabs(p1.y - p2.y) > EPS) return p1.y < p2.y;
		return p1.z + EPS < p2.z;
	}

	bool operator==(const PT3& p1, const PT3& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS && fabs(p1.z - p2.z) < EPS;
	}

	PT3 operator-(PT3 p) {
		return PT3(-p.x, -p.y, -p.z);
	}

	PT3 operator+(PT3 p1, PT3 p2) {
		return PT3(p1.x + p2.x, p1.y + p2.y, p1.z + p2.z);
	}

	PT3 operator-(PT3 p1, PT3 p2) {
		return PT3(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z);
	}

	PT3 operator*(PT3 p, DB c) {
		return PT3(p.x * c, p.y * c, p.z * c);
	}

	PT3 operator/(PT3 p, DB c) {
		return PT3(p.x / c, p.y / c, p.z / c);
	}

	DB dist(PT3 P) {
		return P.len();
	}

	DB dis2(PT3 p1, PT3 p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y) + sqr(p1.z - p2.z);
	}

	DB dis(PT3 p1, PT3 p2) {
		return sqrt(dis2(p1, p2));
	}

	PT3 vect(PT3 p1, PT3 p2) {
		return PT3(p1.y * p2.z - p2.y * p1.z, -(p1.x * p2.z - p2.x * p1.z), p1.x * p2.y - p2.x * p1.y);
	}

	DB scal(PT3 p1, PT3 p2) {
		return p1.x * p2.x + p1.y * p2.y + p1.z * p2.z;
	}

	PT3 vect(PT3 p, PT3 p1, PT3 p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT3 p, PT3 p1, PT3 p2) {
		return scal(p1 - p, p2 - p);
	}
	//get norm of vector a
	PT3 normalize(PT3 a) {
		return a / sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
	}
	//get norm of virtically with plane abc.
	PT3 norm(PT3 a, PT3 b, PT3 c) {
		return normalize(vect(b - a, c - a)) ;
	}

	// Get Equation
	void GetEquation(PT3 A, PT3 B, PT3 C, DB &a, DB &b, DB &c, DB &d) {
		PT3 DIR = vect(B - A, C - A);
		a = DIR.x, b = DIR.y, c = DIR.z;
		d = - a * A.x - b * A.y - c * A.z;
	}

	DB GetValue(DB a, DB b, DB c, DB d, PT3 A) {
		return a * A.x + b * A.y + c * A.z + d;
	}

	// rotating points p* on plane abc to plane oxy;
	void rotate(PT3 *p, PT3 *q, int n, PT3 a, PT3 b, PT3 c) {
		PT3 pole = norm(a, b, c) ;
		PT3 polex;
		if (pole.x != 0 || pole.y != 0) polex = normalize(PT3(-pole.y, pole.x, 0));
		else polex = normalize(PT3(0, -pole.z, pole.y));
		PT3 poley = normalize(vect(pole, polex));
		DB hiv = scal(pole, p[0]);
		DB lov = hiv;
		for (int i = 0; i < n; i ++) {
			DB v = scal(pole, p[i]);
			hiv = max(v, hiv);
			lov = min(v, lov);
			DB x = scal(polex, p[i]);
			DB y = scal(poley, p[i]);
			DB z = scal(pole, p[i]);
			q[i] = PT3(x, y, z);
		}
	}

	DB disToPlane(PT3 p, DB a, DB b, DB c, DB d) {
		return abs(a * p.x + b * p.y + c * p.z + d) / sqrt(sqr(a) + sqr(b) + sqr(c));
	}

	// Projecting Point To Plane
	PT3 project(PT3 a, PT3 b, PT3 c, PT3 d) {
		PT3 tp = vect(b, c, d);
		return a - (tp * scal(tp, a - b) / scal(tp, tp));
	}

	void make_plane(PT3 p, PT3 p1, PT3 p2, DB& a, DB& b, DB& c, DB& d) {
		PT3 q = vect(p, p1, p2);
		a = q.x, b = q.y, c = q.z;
		d = -(a * p.x + b * p.y + c * p.z);
	}

	// Relation between Plane abc and Segment de
	int INTERSECT(PT3 a, PT3 b, PT3 c, PT3 d, PT3 e, PT3 &res) {
		/*
		Relation between Plain abc and Segment de...
		return 0: Pass by each other.
		return 1: Parallel but not contained.
		return 2: Intersect.
		return 3: Segment is contained on the plain.
		*/
		DB A, B, C, D;
		GetEquation(a, b, c, A, B, C, D);
		DB t1 = GetValue(A, B, C, D, d);
		DB t2 = GetValue(A, B, C, D, e);
		if (t1 > t2) swap(t1, t2), swap(d, e);
		if (fabs(t1) < EPS && fabs(t2) < EPS) {
			res = d;
			return 3;
		}
		if (fabs(t1) < EPS) {
			res = d;
			return 2;
		}
		if (fabs(t2) < EPS) {
			res = e;
			return 0;
		}
		if ((t1 > 0 && t2 > 0) || (t1 < 0 && t2 < 0)) {
			if (fabs(t1 - t2) < EPS) return 1;
			return 0;
		}
		DB Ratio = t1 / (t1 - t2);
		res = d + ((e - d) * Ratio);
		return 2;
	}
};
using namespace G3;

namespace G2{
	struct PT {
		DB x, y;

		PT() {}
		PT(DB x, DB y) : x(x), y(y) {}
	};

	bool operator<(const PT& p1, const PT& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		return p1.y + EPS < p2.y;
	}

	bool operator==(const PT& p1, const PT& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS;
	}

	PT operator+(PT p1, PT p2) {
		return PT(p1.x + p2.x, p1.y + p2.y);
	}

	PT operator-(PT p1, PT p2) {
		return PT(p1.x - p2.x, p1.y - p2.y);
	}

	PT operator*(PT p, DB c) {
		return PT(p.x * c, p.y * c);
	}

	PT operator/(PT p, DB c) {
		return PT(p.x / c, p.y / c);
	}

	DB dis(PT p) {
		return sqrt(sqr(p.x) + sqr(p.y));
	}

	DB dis2(PT p) {
		return sqr(p.x) + sqr(p.y);
	}

	PT rot(PT p, DB t) {
		return PT(p.x * cos(t) - p.y * sin(t), p.x * sin(t) + p.y * cos(t));
	}

	PT polar(PT p, DB r, DB t) {
		return PT(p.x + r * cos(t), p.y + r * sin(t));
	}

	DB dis2(PT p1, PT p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y);
	}

	DB dis(PT p1, PT p2) {
		return sqrt(dis2(p1, p2));
	}

	DB vect(PT p1, PT p2) {
		return p1.x * p2.y - p2.x * p1.y;
	}

	DB scal(PT p1, PT p2) {
		return p1.x * p2.x + p1.y * p2.y;
	}

	DB vect(PT p, PT p1, PT p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT p, PT p1, PT p2) {
		return scal(p1 - p, p2 - p);
	}

	bool onLine(PT p, PT p1, PT p2) {
		return fabs(vect(p1 - p, p2 - p)) < EPS;
	}

	bool onSeg(PT p, PT p1, PT p2) {
		if (!onLine(p, p1, p2)) return 0;
		return (p1.x - p.x) * (p2.x - p.x) < EPS && (p1.y - p.y) * (p2.y - p.y) < EPS;
	}

	PT projection(PT a, PT b, PT p) {
		return a + (a - b) * scal(p - a, a - b) / dis2(a - b);
	}

	int posLineLine(PT p1, PT p2, PT p3, PT p4, PT& p) {
		DB s1 = vect(p1, p2, p3), s2 = vect(p1, p2, p4);
		if (fabs(s1 - s2) < EPS) {
			if (fabs(s1) < EPS) return 2;
			return 0;
		}
		p = p3 + (p4 - p3) * s1 / (s1 - s2);
		return 1;
	}
};
using namespace G2;

const int N = 110000;
PT3 P[N], Q[N], _P[N], _Q[N];
PT p[N];

int main() {
//	freopen("in.txt", "r", stdin);
	ios_base::sync_with_stdio(0);
	int n, m; cin >> n;
	for (int i = 0; i < n; i++) P[i].in();
	cin >> m;
	for (int i = 0; i < m; i++) Q[i].in();
	rotate(P, _P, n, P[0], P[1], P[2]);
	rotate(Q, _Q, m, P[0], P[1], P[2]);
	for (int i = 0; i < n; i++) P[i] = _P[i], p[i] = PT(P[i].x, P[i].y);
	for (int i = 0; i < m; i++) Q[i] = _Q[i];
	int flg = 0;
	vector<PT> vec;
	for (int i = 0; i < m; i++) {
		PT3 res;
		if (INTERSECT(P[0], P[1], P[2], Q[i], Q[(i + 1) % m], res) == 2) vec.push_back(PT(res.x, res.y));
	}
	if (!vec.size() || flg) return puts("NO"), 0;
	if (vec.size() & 1) while (1);
	sort(vec.begin(), vec.end());
	PT A = vec[0], B = vec.back();
	DB l = dis(A, B);
	if (fabs(l) < EPS) return puts("NO"), 0;
	vector<DB> vd;
	vector<pair<DB, int>> vp;
	for (auto &t : vec) vd.push_back(dis(A, t) / l);
	for (int i = 0; i < n; i++) {
		PT res;
		int ret = posLineLine(p[i], p[(i + 1) % n], A, B, res);
		if (ret == 1 && onSeg(res, p[i], p[(i + 1) % n]) && dis(res, p[i]) > EPS) {
			int dir = -1;
			if (vect(p[i], A, B) < 0) dir = 1;
			DB d = dis(res, A) / l;
			if (onSeg(A, res, B)) d *= -1;
			vp.emplace_back(d, dir);
		}
	}
	sort(vp.begin(), vp.end());
	assert(vp.size() % 2 == 0);
	int vn = 0, cnt = 0;
	for (int i = 0; i < vd.size(); i += 2) {
		DB from = vd[i], to = vd[i + 1];
		while (vn < vp.size() && vp[vn].first < from) vn++;
		while (vn < vp.size() && vp[vn].first < to) cnt += vp[vn].second, vn++;
	}
	cnt ? puts("YES") : puts("NO");
}


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

typedef double DB;
const DB PI = acos(DB(-1));
const DB INF = 1e10;
const DB EPS = 1e-8;

inline DB sqr(DB x) {
	return x * x;
}

namespace G3{
	struct PT3 {
		DB x, y, z;

		PT3() {}
		PT3(DB x, DB y, DB z) : x(x), y(y), z(z) {}

		void in() {
			cin >> x >> y >> z;
		}
		DB len() {
			return sqrt(sqr(x) + sqr(y) + sqr(z));
		}
	};

	bool operator<(const PT3& p1, const PT3& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		if (fabs(p1.y - p2.y) > EPS) return p1.y < p2.y;
		return p1.z + EPS < p2.z;
	}

	bool operator==(const PT3& p1, const PT3& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS && fabs(p1.z - p2.z) < EPS;
	}

	PT3 operator-(PT3 p) {
		return PT3(-p.x, -p.y, -p.z);
	}

	PT3 operator+(PT3 p1, PT3 p2) {
		return PT3(p1.x + p2.x, p1.y + p2.y, p1.z + p2.z);
	}

	PT3 operator-(PT3 p1, PT3 p2) {
		return PT3(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z);
	}

	PT3 operator*(PT3 p, DB c) {
		return PT3(p.x * c, p.y * c, p.z * c);
	}

	PT3 operator/(PT3 p, DB c) {
		return PT3(p.x / c, p.y / c, p.z / c);
	}

	DB dist(PT3 P) {
		return P.len();
	}

	DB dis2(PT3 p1, PT3 p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y) + sqr(p1.z - p2.z);
	}

	DB dis(PT3 p1, PT3 p2) {
		return sqrt(dis2(p1, p2));
	}

	PT3 vect(PT3 p1, PT3 p2) {
		return PT3(p1.y * p2.z - p2.y * p1.z, -(p1.x * p2.z - p2.x * p1.z), p1.x * p2.y - p2.x * p1.y);
	}

	DB scal(PT3 p1, PT3 p2) {
		return p1.x * p2.x + p1.y * p2.y + p1.z * p2.z;
	}

	PT3 vect(PT3 p, PT3 p1, PT3 p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT3 p, PT3 p1, PT3 p2) {
		return scal(p1 - p, p2 - p);
	}
	//get norm of vector a
	PT3 normalize(PT3 a) {
		return a / sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
	}
	//get norm of virtically with plane abc.
	PT3 norm(PT3 a, PT3 b, PT3 c) {
		return normalize(vect(b - a, c - a)) ;
	}

	// Get Equation
	void GetEquation(PT3 A, PT3 B, PT3 C, DB &a, DB &b, DB &c, DB &d) {
		PT3 DIR = vect(B - A, C - A);
		a = DIR.x, b = DIR.y, c = DIR.z;
		d = - a * A.x - b * A.y - c * A.z;
	}

	DB GetValue(DB a, DB b, DB c, DB d, PT3 A) {
		return a * A.x + b * A.y + c * A.z + d;
	}

	// rotating points p* on plane abc to plane oxy;
	void rotate(PT3 *p, PT3 *q, int n, PT3 a, PT3 b, PT3 c) {
		PT3 pole = norm(a, b, c) ;
		PT3 polex;
		if (pole.x != 0 || pole.y != 0) polex = normalize(PT3(-pole.y, pole.x, 0));
		else polex = normalize(PT3(0, -pole.z, pole.y));
		PT3 poley = normalize(vect(pole, polex));
		DB hiv = scal(pole, p[0]);
		DB lov = hiv;
		for (int i = 0; i < n; i ++) {
			DB v = scal(pole, p[i]);
			hiv = max(v, hiv);
			lov = min(v, lov);
			DB x = scal(polex, p[i]);
			DB y = scal(poley, p[i]);
			DB z = scal(pole, p[i]);
			q[i] = PT3(x, y, z);
		}
	}

	DB disToPlane(PT3 p, DB a, DB b, DB c, DB d) {
		return abs(a * p.x + b * p.y + c * p.z + d) / sqrt(sqr(a) + sqr(b) + sqr(c));
	}

	// Projecting Point To Plane
	PT3 project(PT3 a, PT3 b, PT3 c, PT3 d) {
		PT3 tp = vect(b, c, d);
		return a - (tp * scal(tp, a - b) / scal(tp, tp));
	}

	void make_plane(PT3 p, PT3 p1, PT3 p2, DB& a, DB& b, DB& c, DB& d) {
		PT3 q = vect(p, p1, p2);
		a = q.x, b = q.y, c = q.z;
		d = -(a * p.x + b * p.y + c * p.z);
	}

	// Relation between Plane abc and Segment de
	int INTERSECT(PT3 a, PT3 b, PT3 c, PT3 d, PT3 e, PT3 &res) {
		/*
		Relation between Plain abc and Segment de...
		return 0: Pass by each other.
		return 1: Parallel but not contained.
		return 2: Intersect.
		return 3: Segment is contained on the plain.
		*/
		DB A, B, C, D;
		GetEquation(a, b, c, A, B, C, D);
		DB t1 = GetValue(A, B, C, D, d);
		DB t2 = GetValue(A, B, C, D, e);
		if (fabs(t1) < EPS && fabs(t2) < EPS) {
			res = d;
			return 3;
		}
		if (fabs(t1) < EPS) {
			res = d;
			return 2;
		}
		if (fabs(t2) < EPS) {
			res = e;
			return 2;
		}
		if ((t1 > 0 && t2 > 0) || (t1 < 0 && t2 < 0)) {
			if (fabs(t1 - t2) < EPS) return 1;
			return 0;
		}
		DB Ratio = t1 / (t1 - t2);
		res = d + ((e - d) * Ratio);
		return 2;
	}
};
using namespace G3;

namespace G2{
	struct PT {
		DB x, y;

		PT() {}
		PT(DB x, DB y) : x(x), y(y) {}
	};

	bool operator<(const PT& p1, const PT& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		return p1.y + EPS < p2.y;
	}

	bool operator==(const PT& p1, const PT& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS;
	}

	PT operator+(PT p1, PT p2) {
		return PT(p1.x + p2.x, p1.y + p2.y);
	}

	PT operator-(PT p1, PT p2) {
		return PT(p1.x - p2.x, p1.y - p2.y);
	}

	PT operator*(PT p, DB c) {
		return PT(p.x * c, p.y * c);
	}

	PT operator/(PT p, DB c) {
		return PT(p.x / c, p.y / c);
	}

	DB dis(PT p) {
		return sqrt(sqr(p.x) + sqr(p.y));
	}

	DB dis2(PT p) {
		return sqr(p.x) + sqr(p.y);
	}

	PT rot(PT p, DB t) {
		return PT(p.x * cos(t) - p.y * sin(t), p.x * sin(t) + p.y * cos(t));
	}

	PT polar(PT p, DB r, DB t) {
		return PT(p.x + r * cos(t), p.y + r * sin(t));
	}

	DB dis2(PT p1, PT p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y);
	}

	DB dis(PT p1, PT p2) {
		return sqrt(dis2(p1, p2));
	}

	DB vect(PT p1, PT p2) {
		return p1.x * p2.y - p2.x * p1.y;
	}

	DB scal(PT p1, PT p2) {
		return p1.x * p2.x + p1.y * p2.y;
	}

	DB vect(PT p, PT p1, PT p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT p, PT p1, PT p2) {
		return scal(p1 - p, p2 - p);
	}

	bool onLine(PT p, PT p1, PT p2) {
		return fabs(vect(p1 - p, p2 - p)) < EPS;
	}

	bool onSeg(PT p, PT p1, PT p2) {
		if (!onLine(p, p1, p2)) return 0;
		return (p1.x - p.x) * (p2.x - p.x) < EPS && (p1.y - p.y) * (p2.y - p.y) < EPS;
	}

	PT projection(PT a, PT b, PT p) {
		return a + (a - b) * scal(p - a, a - b) / dis2(a - b);
	}

	int posLineLine(PT p1, PT p2, PT p3, PT p4, PT& p) {
		DB s1 = vect(p1, p2, p3), s2 = vect(p1, p2, p4);
		if (fabs(s1 - s2) < EPS) {
			if (fabs(s1) < EPS) return 2;
			return 0;
		}
		p = p3 + (p4 - p3) * s1 / (s1 - s2);
		return 1;
	}
};
using namespace G2;

const int N = 110000;
PT3 P[N], Q[N], _P[N], _Q[N];
PT p[N];

int main() {
//	freopen("in.txt", "r", stdin);
	ios_base::sync_with_stdio(0);
	int n, m; cin >> n;
	for (int i = 0; i < n; i++) P[i].in();
	cin >> m;
	for (int i = 0; i < m; i++) Q[i].in();
	rotate(P, _P, n, P[0], P[1], P[2]);
	rotate(Q, _Q, m, P[0], P[1], P[2]);
	for (int i = 0; i < n; i++) P[i] = _P[i], p[i] = PT(P[i].x, P[i].y), assert(P[i].z < EPS);
	for (int i = 0; i < m; i++) Q[i] = _Q[i];
	int flg = 0;
	vector<PT> vec;
	for (int i = 0; i < m; i++) {
		PT3 res;
		if (INTERSECT(P[0], P[1], P[2], Q[i], Q[(i + 1) % m], res) == 2) vec.push_back(PT(res.x, res.y));
	}
	if (!vec.size() || flg) return puts("YES"), 0;
	sort(vec.begin(), vec.end());
	assert(vec.size() % 2 == 0);
	PT A = vec[0], B = vec.back();
	DB l = dis(A, B);
	vector<DB> vd, vp;
	for (auto &t : vec) vd.push_back(dis(A, t) / l);
	for (int i = 0; i < n; i++) {
		PT res;
		int ret = posLineLine(p[i], p[(i + 1) % n], A, B, res);
		if (ret == 1) {
			DB d = dis(res, A) / l;
			if (onSeg(A, res, B)) d *= -1;
			vp.push_back(d);
		}
	}
	sort(vp.begin(), vp.end());
	assert(vp.size() % 2 == 0);
	int vn = 0, cnt = 0;
	for (int i = 0; i < vp.size(); i += 2) {
		DB from = vp[i], to = vp[i + 1];
		while (vn < vd.size() && vd[vn] < from) vn++;
		while (vn < vd.size() && vd[vn] < to) vn++, cnt++;
	}
	cnt & 1 ? puts("NO") : puts("YES");
}


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

typedef long double DB;
const DB PI = acos(DB(-1));
const DB INF = 1e10;
const DB EPS = 1e-8;

inline DB sqr(DB x) {
	return x * x;
}

namespace G3{
	struct PT3 {
		DB x, y, z;

		PT3() {}
		PT3(DB x, DB y, DB z) : x(x), y(y), z(z) {}

		void in() {
			cin >> x >> y >> z;
		}
		DB len() {
			return sqrt(sqr(x) + sqr(y) + sqr(z));
		}
	};

	bool operator<(const PT3& p1, const PT3& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		if (fabs(p1.y - p2.y) > EPS) return p1.y < p2.y;
		return p1.z + EPS < p2.z;
	}

	bool operator==(const PT3& p1, const PT3& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS && fabs(p1.z - p2.z) < EPS;
	}

	PT3 operator-(PT3 p) {
		return PT3(-p.x, -p.y, -p.z);
	}

	PT3 operator+(PT3 p1, PT3 p2) {
		return PT3(p1.x + p2.x, p1.y + p2.y, p1.z + p2.z);
	}

	PT3 operator-(PT3 p1, PT3 p2) {
		return PT3(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z);
	}

	PT3 operator*(PT3 p, DB c) {
		return PT3(p.x * c, p.y * c, p.z * c);
	}

	PT3 operator/(PT3 p, DB c) {
		return PT3(p.x / c, p.y / c, p.z / c);
	}

	DB dist(PT3 P) {
		return P.len();
	}

	DB dis2(PT3 p1, PT3 p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y) + sqr(p1.z - p2.z);
	}

	DB dis(PT3 p1, PT3 p2) {
		return sqrt(dis2(p1, p2));
	}

	PT3 vect(PT3 p1, PT3 p2) {
		return PT3(p1.y * p2.z - p2.y * p1.z, -(p1.x * p2.z - p2.x * p1.z), p1.x * p2.y - p2.x * p1.y);
	}

	DB scal(PT3 p1, PT3 p2) {
		return p1.x * p2.x + p1.y * p2.y + p1.z * p2.z;
	}

	PT3 vect(PT3 p, PT3 p1, PT3 p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT3 p, PT3 p1, PT3 p2) {
		return scal(p1 - p, p2 - p);
	}
	//get norm of vector a
	PT3 normalize(PT3 a) {
		return a / sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
	}
	//get norm of virtically with plane abc.
	PT3 norm(PT3 a, PT3 b, PT3 c) {
		return normalize(vect(b - a, c - a)) ;
	}

	// Get Equation
	void GetEquation(PT3 A, PT3 B, PT3 C, DB &a, DB &b, DB &c, DB &d) {
		PT3 DIR = vect(B - A, C - A);
		a = DIR.x, b = DIR.y, c = DIR.z;
		d = - a * A.x - b * A.y - c * A.z;
	}

	DB GetValue(DB a, DB b, DB c, DB d, PT3 A) {
		return a * A.x + b * A.y + c * A.z + d;
	}

	// rotating points p* on plane abc to plane oxy;
	void rotate(PT3 *p, PT3 *q, int n, PT3 a, PT3 b, PT3 c) {
		PT3 pole = norm(a, b, c) ;
		PT3 polex;
		if (pole.x != 0 || pole.y != 0) polex = normalize(PT3(-pole.y, pole.x, 0));
		else polex = normalize(PT3(0, -pole.z, pole.y));
		PT3 poley = normalize(vect(pole, polex));
		DB hiv = scal(pole, p[0]);
		DB lov = hiv;
		for (int i = 0; i < n; i ++) {
			DB v = scal(pole, p[i]);
			hiv = max(v, hiv);
			lov = min(v, lov);
			DB x = scal(polex, p[i]);
			DB y = scal(poley, p[i]);
			DB z = scal(pole, p[i]);
			q[i] = PT3(x, y, z);
		}
	}

	DB disToPlane(PT3 p, DB a, DB b, DB c, DB d) {
		return abs(a * p.x + b * p.y + c * p.z + d) / sqrt(sqr(a) + sqr(b) + sqr(c));
	}

	// Projecting Point To Plane
	PT3 project(PT3 a, PT3 b, PT3 c, PT3 d) {
		PT3 tp = vect(b, c, d);
		return a - (tp * scal(tp, a - b) / scal(tp, tp));
	}

	void make_plane(PT3 p, PT3 p1, PT3 p2, DB& a, DB& b, DB& c, DB& d) {
		PT3 q = vect(p, p1, p2);
		a = q.x, b = q.y, c = q.z;
		d = -(a * p.x + b * p.y + c * p.z);
	}

	// Relation between Plane abc and Segment de
	int INTERSECT(PT3 a, PT3 b, PT3 c, PT3 d, PT3 e, PT3 &res) {
		/*
		Relation between Plain abc and Segment de...
		return 0: Pass by each other.
		return 1: Parallel but not contained.
		return 2: Intersect.
		return 3: Segment is contained on the plain.
		*/
		DB A, B, C, D;
		GetEquation(a, b, c, A, B, C, D);
		DB t1 = GetValue(A, B, C, D, d);
		DB t2 = GetValue(A, B, C, D, e);
		if (t1 > t2) swap(t1, t2), swap(d, e);
		if (fabs(t1) < EPS && fabs(t2) < EPS) {
			res = d;
			return 3;
		}
		if (fabs(t1) < EPS) {
			res = d;
			return 2;
		}
		if (fabs(t2) < EPS) {
			res = e;
			return 0;
		}
		if ((t1 > 0 && t2 > 0) || (t1 < 0 && t2 < 0)) {
			if (fabs(t1 - t2) < EPS) return 1;
			return 0;
		}
		DB Ratio = t1 / (t1 - t2);
		res = d + ((e - d) * Ratio);
		return 2;
	}
};
using namespace G3;

namespace G2{
	struct PT {
		DB x, y;

		PT() {}
		PT(DB x, DB y) : x(x), y(y) {}
	};

	bool operator<(const PT& p1, const PT& p2) {
		if (fabs(p1.x - p2.x) > EPS) return p1.x < p2.x;
		return p1.y + EPS < p2.y;
	}

	bool operator==(const PT& p1, const PT& p2) {
		return fabs(p1.x - p2.x) < EPS && fabs(p1.y - p2.y) < EPS;
	}

	PT operator+(PT p1, PT p2) {
		return PT(p1.x + p2.x, p1.y + p2.y);
	}

	PT operator-(PT p1, PT p2) {
		return PT(p1.x - p2.x, p1.y - p2.y);
	}

	PT operator*(PT p, DB c) {
		return PT(p.x * c, p.y * c);
	}

	PT operator/(PT p, DB c) {
		return PT(p.x / c, p.y / c);
	}

	DB dis(PT p) {
		return sqrt(sqr(p.x) + sqr(p.y));
	}

	DB dis2(PT p) {
		return sqr(p.x) + sqr(p.y);
	}

	PT rot(PT p, DB t) {
		return PT(p.x * cos(t) - p.y * sin(t), p.x * sin(t) + p.y * cos(t));
	}

	PT polar(PT p, DB r, DB t) {
		return PT(p.x + r * cos(t), p.y + r * sin(t));
	}

	DB dis2(PT p1, PT p2) {
		return sqr(p1.x - p2.x) + sqr(p1.y - p2.y);
	}

	DB dis(PT p1, PT p2) {
		return sqrt(dis2(p1, p2));
	}

	DB vect(PT p1, PT p2) {
		return p1.x * p2.y - p2.x * p1.y;
	}

	DB scal(PT p1, PT p2) {
		return p1.x * p2.x + p1.y * p2.y;
	}

	DB vect(PT p, PT p1, PT p2) {
		return vect(p1 - p, p2 - p);
	}

	DB scal(PT p, PT p1, PT p2) {
		return scal(p1 - p, p2 - p);
	}

	bool onLine(PT p, PT p1, PT p2) {
		return fabs(vect(p1 - p, p2 - p)) < EPS;
	}

	bool onSeg(PT p, PT p1, PT p2) {
		if (!onLine(p, p1, p2)) return 0;
		return (p1.x - p.x) * (p2.x - p.x) < EPS && (p1.y - p.y) * (p2.y - p.y) < EPS;
	}

	PT projection(PT a, PT b, PT p) {
		return a + (a - b) * scal(p - a, a - b) / dis2(a - b);
	}

	int posLineLine(PT p1, PT p2, PT p3, PT p4, PT& p) {
		DB s1 = vect(p1, p2, p3), s2 = vect(p1, p2, p4);
		if (fabs(s1 - s2) < EPS) {
			if (fabs(s1) < EPS) return 2;
			return 0;
		}
		p = p3 + (p4 - p3) * s1 / (s1 - s2);
		return 1;
	}
};
using namespace G2;

const int N = 110000;
PT3 P[N], Q[N], _P[N], _Q[N];
PT p[N];

int main() {
//	freopen("in.txt", "r", stdin);
	ios_base::sync_with_stdio(0);
	int n, m; cin >> n;
	for (int i = 0; i < n; i++) P[i].in();
	cin >> m;
	for (int i = 0; i < m; i++) Q[i].in();
	rotate(P, _P, n, P[0], P[1], P[2]);
	rotate(Q, _Q, m, P[0], P[1], P[2]);
	for (int i = 0; i < n; i++) P[i] = _P[i], p[i] = PT(P[i].x, P[i].y);
	for (int i = 0; i < m; i++) Q[i] = _Q[i];
	int flg = 0;
	vector<PT> vec;
	for (int i = 0; i < m; i++) {
		PT3 res;
		if (INTERSECT(P[0], P[1], P[2], Q[i], Q[(i + 1) % m], res) == 2) vec.push_back(PT(res.x, res.y));
	}
	if (!vec.size() || flg) return puts("NO"), 0;
	if (vec.size() & 1) while (1);
	sort(vec.begin(), vec.end());
	PT A = vec[0], B = vec.back();
	DB l = dis(A, B);
	if (fabs(l) < EPS) return puts("NO"), 0;
	vector<DB> vd;
	vector<pair<DB, int>> vp;
	for (auto &t : vec) vd.push_back(dis(A, t) / l);
	for (int i = 0; i < n; i++) {
		PT res;
		PT p1 = p[i], p2 = p[(i + 1) % n];
		int ret = posLineLine(p1, p2, A, B, res);
		if (ret == 1 && onSeg(res, p1, p2)) {
			DB d = dis(res, A) / l;
			if (onSeg(A, res, B)) d *= -1;
			if (vect(p1, A, B) < EPS && vect(p2, A, B) > EPS) vp.emplace_back(d, 1);
			if (vect(p1, A, B) > EPS && vect(p2, A, B) < EPS) vp.emplace_back(d, -1);
		}
	}
	sort(vp.begin(), vp.end());
	assert(vp.size() % 2 == 0);
	int vn = 0, cnt = 0;
	for (int i = 0; i < vd.size(); i += 2) {
		DB from = vd[i], to = vd[i + 1];
		while (vn < vp.size() && vp[vn].first < from) vn++;
		while (vn < vp.size() && vp[vn].first < to) cnt += vp[vn].second, vn++;
	}
	cnt ? puts("YES") : puts("NO");
}