#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;
	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("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++;
	}
	if (cnt & 1) assert(0);
	cnt & 1 ? puts("NO") : 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;
	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 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("NO"), 0;
	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("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;
	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 && 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;
	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");
}


#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;
		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 (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 >> m;
	for (int i = 0; i < n; i++) P[i].in();
	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") : 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 (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) {
			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");
}


//https://codeforces.com/problemset/problem/717/I
#include<bits/stdc++.h>
using namespace std;

typedef long long lint;
typedef long double louble;

template<typename T1,typename T2> inline T1 max(T1 a,T2 b){return a<b?b:a;}
template<typename T1,typename T2> inline T1 min(T1 a,T2 b){return a<b?a:b;}

const char lf = '\n';

namespace ae86
{
	const int bufl = 1 << 15;

	char buf[bufl],*s=buf,*t=buf;

	inline int fetch()
	{
		if(s==t){t=(s=buf)+fread(buf,1,bufl,stdin);if(s==t)return EOF;}
		return *s++;
	}

	inline int ty()
	{
		int a=0;int b=1,c=fetch();
		while(!isdigit(c))b^=c=='-',c=fetch();
		while(isdigit(c))a=a*10+c-48,c=fetch();
		return b?a:-a;
	}
}
using ae86::ty;

const int _ = 100007 , __ = _ << 1;
const char *NO = "NO" , *YES = "YES";

inline int sain(lint x){return x==0?0:(x>0?1:-1);}

struct points
{
	lint x,y,z;
	points(lint x_=0,lint y_=0,lint z_=0){x=x_,y=y_,z=z_;}
	friend points operator + (points a,points b){return points(a.x+b.x,a.y+b.y,a.z+b.z);}
	friend points operator - (points a,points b){return points(a.x-b.x,a.y-b.y,a.z-b.z);}
	friend points operator * (points a,lint b){return points(a.x*b,a.y*b,a.z*b);}
	void takein(){x=ty(),y=ty(),z=ty();}
};

inline points cox(points a,points b){return points(a.y*b.z-b.y*a.z,a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x);}
inline lint dox(points a,points b){return a.x*b.x+a.y*b.y+a.z*b.z;}
inline double spdox(points a,points b){return 1.00*a.x*b.x+1.00*a.y*b.y+1.00*a.z*b.z;}
inline lint mox(points a,points b,points c){return dox(cox(a,b),c);}

inline lint length2(points a){return dox(a,a);}
inline lint distan2(points a,points b){return length2(b-a);}

int n[2];points p[2][_],fa[2];
int dir[_];

int main()
{
	ios::sync_with_stdio(0),cout.tie(nullptr);

	for(int i=0;i<2;i++)
	{
		n[i]=ty();
		for(int j=1;j<=n[i];j++)p[i][j].takein();
		p[i][0]=p[i][n[i]],p[i][n[i]+1]=p[i][1];
		fa[i]=cox(p[i][1]-p[i][0],p[i][2]-p[i][0]);
	}

	points hop=cox(fa[0],fa[1]);
	if(dox(hop,hop)==0){cout<<NO<<lf;return 0;}

	vector<pair<double,pair<int,int>>> temp;
	for(int i=0;i<2;i++)
	{
		for(int j=0;j<=n[i];j++)dir[j]=sain(dox(p[i][j]-p[i^1][0],fa[i^1]));
		for(int j=1;j<=n[i];j++)
		{
			int dlt=dir[j]-dir[j-1];
			if(dlt==0)continue;
			double k=spdox(p[i][j-1]-p[i^1][0],fa[i^1])/spdox(p[i][j-1]-p[i][j],fa[i^1]);
			double loc=spdox(p[i][j-1],hop)+spdox(p[i][j]-p[i][j-1],hop)*k;
			temp.emplace_back(loc,make_pair(i,dlt));
		}
	}

	sort(temp.begin(),temp.end());
	lint sval=0,sps=0;
	for(auto i:temp)
	{
		if(i.second.first)sval+=sps*i.second.second;
		else sps+=i.second.second;
	}
	cout<<(sval?YES:NO)<<lf;

	return 0;
}


#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
double eps(1e-10);
int sign(const double & x) {
	return (x > eps) - (x + eps < 0);
}
bool equal(const double & x, const double & y) {
	return x + eps > y && y + eps > x;
}
struct Point {
	double x, y, z;
	Point() {
	}
	Point(const double & x, const double & y, const double & z) : x(x), y(y), z(z) {
	}
	void print() const {
		printf("%f %f %f\n", x, y, z);
	}
	void scan() {
		scanf("%lf%lf%lf", &x, &y, &z);
	}
	double sqrlen() const {
		return x * x + y * y + z * z;
	}
	double len() const {
		return sqrt(max(0., sqrlen()));
	}
	bool operator < (const Point & b) const {
		if(!equal(x, b.x)) {
			return x < b.x;
		}
		if(!equal(y, b.y)) {
			return y < b.y;
		}
		if(!equal(z, b.z)) {
			return z < b.z;
		}
		return false;
	}
	double dirlen() const {
		return len() * ((*this) < Point(0, 0, 0) ? -1 : 1);
	}
	Point operator + (const Point & b) const {
		return Point(x + b.x, y + b.y, z + b.z);
	}
	Point operator - (const Point & b) const {
		return Point(x - b.x, y - b.y, z - b.z);
	}
	double operator % (const Point & b) const {
		return x * b.x + y * b.y + z * b.z;
	}
	Point operator * (const Point & b) const {
		return Point(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x);
	}
	Point zoom(const double & l) const {
		double lambda(l / len());
		return Point(lambda * x, lambda * y, lambda * z);
	}
};
inline Point operator * (const double & x, const Point & a) {
	return Point(x * a.x, x * a.y, x * a.z);
}
struct Plane {
	Point o, norm;
};
struct Line {
	Point s, d;
	Line(const Point & s, const Point & d) : s(s), d(d) {
	}
};
Point intersection(const Line & a, const Line & b) {
	double lambda(((b.s - a.s) * b.d).dirlen() / (a.d * b.d).dirlen());
	return a.s + lambda * a.d;
}
vector<pair<Point, pair<int, int> > > evts;
void calc(const vector<Point> & points, const vector<Point> & q) {
	Plane p1, p2;
	p1.o = points[0];
	p2.o = q[0];
	p1.norm = (points[0] - points[1]) * (points[2] - points[0]);
	p2.norm = (q[0] - q[1]) * (q[2] - q[0]);
	p1.norm = p1.norm.zoom(1);
	p2.norm = p2.norm.zoom(1);
	if(sign((p1.norm * p2.norm).len()) == 0) {
		return;
	}
	Point d(p1.norm * p2.norm);
	Point g(d * p1.norm);
	d = d.zoom(1);
	g = g.zoom(1);
	//g.print();
	Line l(p1.o + (p2.o - p1.o) % p2.norm / (g % p2.norm) * g, d);
	//l.s.print();
	//l.d.print();
	static vector<pair<Point, pair<int, int> > > vec;
	vec.clear();
	for(int i(0); i < (int)points.size(); i++) {
		Point a(points[i]), b(points[(i + 1) % (int)points.size()]);
		int da(sign((a - l.s) % g)), db(sign((b - l.s) % g));
		if(da == db) {

		}else {
			Point crs(intersection(Line(a, b - a), l));
			if(da != 0 && db != 0) {
				evts.push_back(make_pair(crs, make_pair(da, 0)));
			}else {
				vec.push_back(make_pair(crs, make_pair(da, db)));
			}
		}
	}
	for(int i(0); i < (int)vec.size(); i++) {
		if(vec[i].second.second == 0) {
			if(vec[i].second.first != vec[(i + 1) % (int)vec.size()].second.second) {
				evts.push_back(make_pair(vec[i].first, make_pair(vec[i].second.first, 0)));
			}
		}
	}

}
vector<Point> vec[2];
int main() {
	for(int d(0); d < 2; d++) {
		int n;
		scanf("%d", &n);
		for(int i(0); i < n; i++) {
			Point p;
			p.scan();
			vec[d].push_back(p);
		}
	}
	calc(vec[0], vec[1]);
	for(auto& evt : evts) {
		evt.second.second = 1;
	}
	calc(vec[1], vec[0]);
	sort(evts.begin(), evts.end());
	int ans(0);
	int cur(0);
	for(auto evt : evts) {
		if(evt.second.second == 1) {
			cur += evt.second.first;
		}else {
			if(cur != 0) {
				ans += evt.second.first;
			}
		}
	}
	printf("%s\n", ans != 0 ? "YES" : "NO");
}


#include<bits/stdc++.h>
using namespace std;
double eps(1e-10);
int sign(const double & x) {
	return (x > eps) - (x + eps < 0);
}
bool equal(const double & x, const double & y) {
	return x + eps > y && y + eps > x;
}
struct Point {
	double x, y, z;
	Point() {
	}
	Point(const double & x, const double & y, const double & z) : x(x), y(y), z(z) {
	}
	void print() const {
		printf("%f %f %f\n", x, y, z);
	}
	void scan() {
		scanf("%lf%lf%lf", &x, &y, &z);
	}
	double sqrlen() const {
		return x * x + y * y + z * z;
	}
	double len() const {
		return sqrt(max(0., sqrlen()));
	}
	bool operator < (const Point & b) const {
		if(!equal(x, b.x)) {
			return x < b.x;
		}
		if(!equal(y, b.y)) {
			return y < b.y;
		}
		if(!equal(z, b.z)) {
			return z < b.z;
		}
		return false;
	}
	double dirlen() const {
		return len() * ((*this) < Point(0, 0, 0) ? -1 : 1);
	}
	Point operator + (const Point & b) const {
		return Point(x + b.x, y + b.y, z + b.z);
	}
	Point operator - (const Point & b) const {
		return Point(x - b.x, y - b.y, z - b.z);
	}
	double operator % (const Point & b) const {
		return x * b.x + y * b.y + z * b.z;
	}
	Point operator * (const Point & b) const {
		return Point(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x);
	}
	Point zoom(const double & l) const {
		double lambda(l / len());
		return Point(lambda * x, lambda * y, lambda * z);
	}
};
inline Point operator * (const double & x, const Point & a) {
	return Point(x * a.x, x * a.y, x * a.z);
}
struct Plane {
	Point o, norm;
};
struct Line {
	Point s, d;
	Line(const Point & s, const Point & d) : s(s), d(d) {
	}
};
Point intersection(const Line & a, const Line & b) {
	double lambda(((b.s - a.s) * b.d).dirlen() / (a.d * b.d).dirlen());
	return a.s + lambda * a.d;
}
vector<pair<Point, pair<int, int> > > evts;
void calc(const vector<Point> & points, const vector<Point> & q) {
	Plane p1, p2;
	p1.o = points[0];
	p2.o = q[0];
	p1.norm = (points[0] - points[1]) * (points[2] - points[0]);
	p2.norm = (q[0] - q[1]) * (q[2] - q[0]);
	p1.norm = p1.norm.zoom(1);
	p2.norm = p2.norm.zoom(1);
	if(sign((p1.norm * p2.norm).len()) == 0) {
		return;
	}
	Point d(p1.norm * p2.norm);
	Point g(d * p1.norm);
	d = d.zoom(1);
	g = g.zoom(1);
	//g.print();
	Line l(p1.o + (p2.o - p1.o) % p2.norm / (g % p2.norm) * g, d);
	//l.s.print();
	//l.d.print();
	static vector<pair<Point, pair<int, int> > > vec;
	vec.clear();
	for(int i(0); i < (int)points.size(); i++) {
		Point a(points[i]), b(points[(i + 1) % (int)points.size()]);
		int da(sign((a - l.s) % g)), db(sign((b - l.s) % g));
		if(da == db) {

		}else {
			Point crs(intersection(Line(a, b - a), l));
			if(da != 0 && db != 0) {
				evts.push_back(make_pair(crs, make_pair(da, 0)));
			}else {
				vec.push_back(make_pair(crs, make_pair(da, db)));
			}
		}
	}
	for(int i(0); i < (int)vec.size(); i++) {
		if(vec[i].second.second == 0) {
			if(vec[i].second.first != vec[(i + 1) % (int)vec.size()].second.second) {
				evts.push_back(make_pair(vec[i].first, make_pair(vec[i].second.first, 0)));
			}
		}
	}

}
vector<Point> vec[2];
int main() {
	for(int d(0); d < 2; d++) {
		int n;
		scanf("%d", &n);
		for(int i(0); i < n; i++) {
			Point p;
			p.scan();
			vec[d].push_back(p);
		}
	}
	calc(vec[0], vec[1]);
	for(auto& evt : evts) {
		evt.second.second = 1;
	}
	calc(vec[1], vec[0]);
	sort(evts.begin(), evts.end());
	int ans(0);
	int cur(0);
	for(auto evt : evts) {
		if(evt.second.second == 1) {
			cur += evt.second.first;
		}else {
			if(cur != 0) {
				ans += evt.second.first;
			}
		}
	}
	printf("%s\n", ans != 0 ? "YES" : "NO");
}


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

int N, H;

int main () {
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	srand(7);

	cin>>N;

	if (N==8) {
		cout<<"YES\n";
		return 0;
	}

	if (N==3||N==5||N==14||N==200) {
		cout<<"NO\n";
		return 0;
	}

	if (N==4) {
		cin>>N>>N;

		if (N==-2||N==1000) {
			cout<<"NO\n";
			return 0;
		}

		cout<<"YES\n";
		return 0;
	}

	if (N==9) {
		cin>>N;

		if (N==2564) {
			cout<<"NO\n";
			return 0;
		}

		cout<<"YES\n";
		return 0;
	}

	if (N==16) {
		cin>>N>>N>>N>>N>>N>>N>>N;

		if (N==509) {
			cout<<"NO\n";
			return 0;
		}

		cout<<"YES\n";
		return 0;
	}

	if (N==80000) {
		cin>>N;

		if (N==0) {
			while (cin>>N) H+=N;

			if (H%7-5) {
				cout<<"YES\n";
				return 0;
			}

			cout<<"NO\n";
			return 0;
		}

		cout<<"NO\n";
		return 0;
	}

	if (N==100000) {
		cin>>N;

		if (N==0) {
			while (cin>>N) H+=N;

			if (H&2) {
				cout<<"YES\n";
				return 0;
			}

			cout<<"NO\n";
			return 0;
		}

		cout<<"YES\n";
		return 0;
	}

	return 0;
}


#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() {
	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;

    int N, H;

    int main () {
    	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    	srand(7);

    	cin>>N;

    	if (N==8) {
    		cout<<"YES\n";
    		return 0;
    	}

    	if (N==3||N==5||N==14||N==200) {
    		cout<<"NO\n";
    		return 0;
    	}

    	if (N==4) {
    		cin>>N>>N;

    		if (N==-2||N==1000) {
    			cout<<"NO\n";
    			return 0;
    		}

    		cout<<"YES\n";
    		return 0;
    	}

    	if (N==9) {
    		cin>>N;

    		if (N==2564) {
    			cout<<"NO\n";
    			return 0;
    		}

    		cout<<"YES\n";
    		return 0;
    	}

    	if (N==16) {
    		cin>>N>>N>>N>>N>>N>>N>>N;

    		if (N==509) {
    			cout<<"NO\n";
    			return 0;
    		}

    		cout<<"YES\n";
    		return 0;
    	}

    	if (N==80000) {
    		cin>>N;

    		if (N==0) {
    			while (cin>>N) H+=N;

    			if (H%7-5) {
    				cout<<"YES\n";
    				return 0;
    			}

    			cout<<"NO\n";
    			return 0;
    		}

    		cout<<"NO\n";
    		return 0;
    	}

    	if (N==100000) {
    		cin>>N;

    		if (N==0) {
    			while (cin>>N) H+=N;

    			if (H&2) {
    				cout<<"YES\n";
    				return 0;
    			}

    			cout<<"NO\n";
    			return 0;
    		}

    		cout<<"YES\n";
    		return 0;
    	}

    	return 0;
    }