//package bubblecup9f;
import java.awt.geom.Line2D;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Comparator;
import java.util.InputMismatchException;
import java.util.Random;

public class I {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni();
		double[][] ca = new double[n][];
		for(int i = 0;i < n;i++){
			ca[i] = new double[]{ni(), ni(), ni()};
		}
		int m = ni();
		double[][] cb = new double[m][];
		for(int i = 0;i < m;i++){
			cb[i] = new double[]{ni(), ni(), ni()};
		}
		double[] a1 = new double[]{ca[1][0]-ca[0][0], ca[1][1]-ca[0][1], ca[1][2]-ca[0][2]};
		double[] a2 = new double[]{ca[2][0]-ca[0][0], ca[2][1]-ca[0][1], ca[2][2]-ca[0][2]};
		double[] na = normalize(cross(a1, a2));

		double[][] vs = new double[n+m][];
		for(int i = 0;i < n;i++){
			vs[i] = ca[i];
		}
		for(int i = 0;i < m;i++){
			vs[i+n] = cb[i];
		}
		double[][] vvs = rot(na, new double[]{0, 0, 1}, vs);
		double Z = 0;
		for(int i = 0;i < n;i++){
			Z += vvs[i][2];
		}
		Z /= n;
		Z += 1e-9;

		double[][] es = new double[m+2*n][];
		int p = 0;
		for(int i = 0, j = 1;i < m;i++,j++){
			if(j == m)j = 0;
			if(vvs[i+n][2] < Z && vvs[j+n][2] > Z){
				if(vvs[j+n][2] != vvs[i+n][2]){
					double k = (Z-vvs[i+n][2])/(vvs[j+n][2]-vvs[i+n][2]);
					es[p++] = new double[]{
							vvs[i+n][0]+k*(vvs[j+n][0]-vvs[i+n][0]),
							vvs[i+n][1]+k*(vvs[j+n][1]-vvs[i+n][1]),
							1
					};
				}
			}else if(vvs[i+n][2] > Z && vvs[j+n][2] < Z){
				if(vvs[j+n][2] != vvs[i+n][2]){
					double k = (Z-vvs[i+n][2])/(vvs[j+n][2]-vvs[i+n][2]);
					es[p++] = new double[]{
							vvs[i+n][0]+k*(vvs[j+n][0]-vvs[i+n][0]),
							vvs[i+n][1]+k*(vvs[j+n][1]-vvs[i+n][1]),
							-1
					};
				}
			}
		}
//		tr(es);
		for(int i = 0, j = 1;i < n;i++,j++){
			if(j == n)j = 0;
			double x0 = vvs[i][0], y0 = vvs[i][1];
			double x1 = vvs[j][0], y1 = vvs[j][1];
			es[p++] = new double[]{Math.min(x0, x1), i, 1, j};
			es[p++] = new double[]{Math.max(x0, x1), i, -1, j};
		}
		Arrays.sort(es, 0, p, new Comparator<double[]>() {
			public int compare(double[] a, double[] b) {
				if(a[0] != b[0])return Double.compare(a[0], b[0]);
				return -Double.compare(a[2], b[2]);
			}
		});

		Node[] nodes = new Node[n];
		Node root = null;
		int bal = 0;
		for(int i = 0;i < p;i++){
			double[] e = es[i];
			if(e.length == 4){
				if(e[2] == 1){
					nodes[(int)e[1]] = new Node(vvs[(int)e[1]], vvs[(int)e[3]]);
					root = insertb(root, nodes[(int)e[1]], i+1 < p ? (e[0]+es[i+1][0])/2 : 1e13);
				}else{
					root = erase(root, index(nodes[(int)e[1]]));
				}
			}else{
//				tr(lowerBound(root, e, e, e[0]));
				if((lowerBound(root, e, e, e[0])&1) == 1){
					bal += (int)e[2];
				}
			}
//			tr(toString(root, ""));
		}
		if(bal != 0){
			out.println("YES");
		}else{
			out.println("NO");
		}
	}

	public static Random gen = new Random(1145);

	static public class Node
	{
		public int v; // value
		public long priority;
		public Node left, right, parent;
		public double[] a, b;

		public int count;

		public Node(double[] a, double[] b)
		{
			if(a[0] > b[0]){
				double[] d = a; a = b; b = d;
			}
			this.a = a;
			this.b = b;
			priority = gen.nextLong();
			update(this);
		}

		@Override
		public String toString() {
			StringBuilder builder = new StringBuilder();
			builder.append("Node [v=");
			builder.append(Arrays.toString(a));
			builder.append(Arrays.toString(b));
			builder.append(", count=");
			builder.append(count);
			builder.append(", parent=");
			builder.append(parent != null ? parent.v : "null");
			builder.append("]");
			return builder.toString();
		}
	}

	public static Node update(Node a)
	{
		if(a == null)return null;
		a.count = 1;
		if(a.left != null)a.count += a.left.count;
		if(a.right != null)a.count += a.right.count;

		// TODO
		return a;
	}

	public static void propagate(Node x)
	{
		for(;x != null;x = x.parent)update(x);
	}

	public static Node disconnect(Node a)
	{
		if(a == null)return null;
		a.left = a.right = a.parent = null;
		return update(a);
	}

	public static Node root(Node x)
	{
		if(x == null)return null;
		while(x.parent != null)x = x.parent;
		return x;
	}

	public static int count(Node a)
	{
		return a == null ? 0 : a.count;
	}

	public static void setParent(Node a, Node par)
	{
		if(a != null)a.parent = par;
	}

	public static Node merge(Node a, Node b, Node... c)
	{
		Node x = merge(a, b);
		for(Node n : c)x = merge(x, n);
		return x;
	}

	public static Node merge(Node a, Node b)
	{
		if(b == null)return a;
		if(a == null)return b;
		if(a.priority > b.priority){
			setParent(a.right, null);
			setParent(b, null);
			a.right = merge(a.right, b);
			setParent(a.right, a);
			return update(a);
		}else{
			setParent(a, null);
			setParent(b.left, null);
			b.left = merge(a, b.left);
			setParent(b.left, b);
			return update(b);
		}
	}

	public static Node[] split(Node x)
	{
		if(x == null)return new Node[]{null, null};
		if(x.left != null)x.left.parent = null;
		Node[] sp = new Node[]{x.left, x};
		x.left = null;
		update(x);
		while(x.parent != null){
			Node p = x.parent;
			x.parent = null;
			if(x == p.left){
				p.left = sp[1];
				if(sp[1] != null)sp[1].parent = p;
				sp[1] = p;
			}else{
				p.right = sp[0];
				if(sp[0] != null)sp[0].parent = p;
				sp[0] = p;
			}
			update(p);
			x = p;
		}
		return sp;
	}

	public static String toString(Node a, String indent)
	{
		if(a == null)return "";
		StringBuilder sb = new StringBuilder();
		sb.append(toString(a.left, indent + "  "));
		sb.append(indent).append(a).append("\n");
		sb.append(toString(a.right, indent + "  "));
		return sb.toString();
	}

	public static Node[] split(Node a, int... ks)
	{
		int n = ks.length;
		if(n == 0)return new Node[]{a};
		for(int i = 0;i < n-1;i++){
			if(ks[i] > ks[i+1])throw new IllegalArgumentException(Arrays.toString(ks));
		}

		Node[] ns = new Node[n+1];
		Node cur = a;
		for(int i = n-1;i >= 0;i--){
			Node[] sp = split(cur, ks[i]);
			cur = sp[0];
			ns[i] = sp[0];
			ns[i+1] = sp[1];
		}
		return ns;
	}

	// [0,K),[K,N)
	public static Node[] split(Node a, int K)
	{
		if(a == null)return new Node[]{null, null};
		if(K <= count(a.left)){
			setParent(a.left, null);
			Node[] s = split(a.left, K);
			a.left = s[1];
			setParent(a.left, a);
			s[1] = update(a);
			return s;
		}else{
			setParent(a.right, null);
			Node[] s = split(a.right, K-count(a.left)-1);
			a.right = s[0];
			setParent(a.right, a);
			s[0] = update(a);
			return s;
		}
	}

	public static Node insertb(Node root, Node x, double midx)
	{
		int ind = lowerBound(root, x.a, x.b, midx);
		return insert(root, ind, x);
	}

	public static Node insert(Node a, int K, Node b)
	{
		if(a == null)return b;
		if(b.priority < a.priority){
			if(K <= count(a.left)){
				a.left = insert(a.left, K, b);
				setParent(a.left, a);
			}else{
				a.right = insert(a.right, K-count(a.left)-1, b);
				setParent(a.right, a);
			}
			return update(a);
		}else{
			Node[] ch = split(a, K);
			b.left = ch[0]; b.right = ch[1];
			setParent(b.left, b);
			setParent(b.right, b);
			return update(b);
		}
	}

	// delete K-th
	public static Node erase(Node a, int K)
	{
		if(a == null)return null;
		if(K < count(a.left)){
			a.left = erase(a.left, K);
			setParent(a.left, a);
			return update(a);
		}else if(K == count(a.left)){
			setParent(a.left, null);
			setParent(a.right, null);
			Node aa = merge(a.left, a.right);
			disconnect(a);
			return aa;
		}else{
			a.right = erase(a.right, K-count(a.left)-1);
			setParent(a.right, a);
			return update(a);
		}
	}

	public static Node get(Node a, int K)
	{
		while(a != null){
			if(K < count(a.left)){
				a = a.left;
			}else if(K == count(a.left)){
				break;
			}else{
				K = K - count(a.left)-1;
				a = a.right;
			}
		}
		return a;
	}

	public static int index(Node a)
	{
		if(a == null)return -1;
		int ind = count(a.left);
		while(a != null){
			Node par = a.parent;
			if(par != null && par.right == a){
				ind += count(par.left) + 1;
			}
			a = par;
		}
		return ind;
	}

//	public static Node mergeTechnically(Node x, Node y)
//	{
//		if(count(x) > count(y)){
//			Node d = x; x = y; y = d;
//		}
//		// |x|<=|y|
//		for(Node cur : nodesdfs(x))y = insertb(y, disconnect(cur));
//		return y;
//	}

	static int robccw(double ux, double uy, double vx, double vy, double px, double py)
	{
		double eps = 1e-8;
		if(Line2D.ptSegDist(ux, uy, vx, vy, px, py) > eps){
			return Line2D.relativeCCW(ux, uy, vx, vy, px, py);
		}
		return 0;
	}

	static double y(double x, double[] a, double[] b)
	{
		if(a == b)return a[1];
		if(b[0]-a[0] == 0)return 1e13;
		return a[1] + (x-a[0])/(b[0]-a[0])*(b[1]-a[1]);
	}
	private static void trz(Object... o) { System.out.println(Arrays.deepToString(o)); }

	public static int lowerBound(Node a, double[] u, double[] v, double x)
	{
		if(u[0] > v[0]){
			double[] d = u; u = v; v = d;
		}
//		trz("LB", u, v, x);
		int lcount = 0;
		while(a != null){
			int comp = 0;
			// --->
			//  * = 1

			// u-v, a.a-a.b
			if(comp == 0 && u != v){
				comp = robccw(u[0], u[1], v[0], v[1], x, y(x, a.a, a.b));
//				trz("rob", u[0], u[1], v[0], v[1], x, y(x, a.a, a.b), comp);
			}
			if(comp == 0){
//				trz("HI", a.a[0], a.a[1], a.b[0], a.b[1], x, y(x, u, v));
				comp = -robccw(a.a[0], a.a[1], a.b[0], a.b[1], x, y(x, u, v));
			}

			if(comp <= 0){
				a = a.left;
			}else{
				lcount += count(a.left) + 1;
				a = a.right;
			}
		}
//		trz(lcount);
		return lcount;
	}

	public static int search(Node a, int q)
	{
		int lcount = 0;
		while(a != null){
			if(a.v == q){
				lcount += count(a.left);
				break;
			}
			if(q < a.v){
				a = a.left;
			}else{
				lcount += count(a.left) + 1;
				a = a.right;
			}
		}
		return a == null ? -(lcount+1) : lcount;
	}

	public static Node next(Node x)
	{
		if(x == null)return null;
		if(x.right != null){
			x = x.right;
			while(x.left != null)x = x.left;
			return x;
		}else{
			while(true){
				Node p = x.parent;
				if(p == null)return null;
				if(p.left == x)return p;
				x = p;
			}
		}
	}

	public static Node prev(Node x)
	{
		if(x == null)return null;
		if(x.left != null){
			x = x.left;
			while(x.right != null)x = x.right;
			return x;
		}else{
			while(true){
				Node p = x.parent;
				if(p == null)return null;
				if(p.right == x)return p;
				x = p;
			}
		}
	}

	public static Node[] nodes(Node a) { return nodes(a, new Node[a.count], 0, a.count); }
	public static Node[] nodes(Node a, Node[] ns, int L, int R)
	{
		if(a == null)return ns;
		nodes(a.left, ns, L, L+count(a.left));
		ns[L+count(a.left)] = a;
		nodes(a.right, ns, R-count(a.right), R);
		return ns;
	}

	// faster than nodes but inconsistent
	public static Node[] nodesdfs(Node a) { return nodesdfs(a, new Node[a.count], new int[]{0}); }
	public static Node[] nodesdfs(Node a, Node[] ns, int[] pos)
	{
		if(a == null)return ns;
		ns[pos[0]++] = a;
		nodesdfs(a.left, ns, pos);
		nodesdfs(a.right, ns, pos);
		return ns;
	}

	public static double[][] rot(double[] from, double[] to, double[][] xs)
	{
		double nfrom = Math.sqrt(from[0]*from[0]+from[1]*from[1]+from[2]*from[2]);
		for(int i = 0;i < 3;i++)from[i] /= nfrom;
		double nto = Math.sqrt(to[0]*to[0]+to[1]*to[1]+to[2]*to[2]);
		for(int i = 0;i < 3;i++)to[i] /= nto;
		double dot = from[0]*to[0]+from[1]*to[1]+from[2]*to[2];
		if(dot >= 1)dot = 1;
		if(dot <= -1)dot = -1;
		double angle = Math.acos(dot);
		if(Math.abs(angle) < 1E-8)return xs;
		if(Math.abs(Math.PI-angle) < 1E-8){
			double[][] ret = new double[xs.length][3];
			for(int i = 0;i < xs.length;i++){
				ret[i][0] = -xs[i][0];
				ret[i][1] = -xs[i][1];
				ret[i][2] = -xs[i][2];
			}
			return ret;
		}

		double[] axis = new double[]{
				from[1]*to[2]-from[2]*to[1],
				from[2]*to[0]-from[0]*to[2],
				from[0]*to[1]-from[1]*to[0]
		};
		double nax = Math.sqrt(axis[0]*axis[0]+axis[1]*axis[1]+axis[2]*axis[2]);
		for(int i = 0;i < 3;i++)axis[i] /= nax;

		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	public static double[] normalize(double[] v)
	{
		double norm = Math.sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
		v[0] /= norm;
		v[1] /= norm;
		v[2] /= norm;
		return v;
	}

	public static double[] cross(double[] a, double[] b)
	{
		return new double[]{
				a[1]*b[2]-a[2]*b[1],
				a[2]*b[0]-a[0]*b[2],
				a[0]*b[1]-a[1]*b[0]
		};
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new I().run(); }

	private byte[] inbuf = new byte[1024];
	private int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


//package bubblecup9f;
import java.awt.geom.Line2D;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Comparator;
import java.util.InputMismatchException;
import java.util.Random;

public class I {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni();
		double[][] ca = new double[n][];
		for(int i = 0;i < n;i++){
			ca[i] = new double[]{ni(), ni(), ni()};
		}
		int m = ni();
		double[][] cb = new double[m][];
		for(int i = 0;i < m;i++){
			cb[i] = new double[]{ni(), ni(), ni()};
		}
		double[] a1 = new double[]{ca[1][0]-ca[0][0], ca[1][1]-ca[0][1], ca[1][2]-ca[0][2]};
		double[] a2 = new double[]{ca[2][0]-ca[0][0], ca[2][1]-ca[0][1], ca[2][2]-ca[0][2]};
		double[] na = normalize(cross(a1, a2));

		double[][] vs = new double[n+m][];
		for(int i = 0;i < n;i++){
			vs[i] = ca[i];
		}
		for(int i = 0;i < m;i++){
			vs[i+n] = cb[i];
		}
		double[][] vvs = rot(na, new double[]{0, 0, 1}, vs);
		double Z = 0;
		for(int i = 0;i < n;i++){
			Z += vvs[i][2];
		}
		Z /= n;
		Z += 1e-9;

		double[][] es = new double[m+2*n][];
		int p = 0;
		for(int i = 0, j = 1;i < m;i++,j++){
			if(j == m)j = 0;
			if(vvs[i+n][2] < Z && vvs[j+n][2] > Z){
				if(vvs[j+n][2] != vvs[i+n][2]){
					double k = (Z-vvs[i+n][2])/(vvs[j+n][2]-vvs[i+n][2]);
					es[p++] = new double[]{
							vvs[i+n][0]+k*(vvs[j+n][0]-vvs[i+n][0]),
							vvs[i+n][1]+k*(vvs[j+n][1]-vvs[i+n][1]),
							1
					};
				}
			}else if(vvs[i+n][2] > Z && vvs[j+n][2] < Z){
				if(vvs[j+n][2] != vvs[i+n][2]){
					double k = (Z-vvs[i+n][2])/(vvs[j+n][2]-vvs[i+n][2]);
					es[p++] = new double[]{
							vvs[i+n][0]+k*(vvs[j+n][0]-vvs[i+n][0]),
							vvs[i+n][1]+k*(vvs[j+n][1]-vvs[i+n][1]),
							-1
					};
				}
			}
		}
//		tr(es);
		for(int i = 0, j = 1;i < n;i++,j++){
			if(j == n)j = 0;
			double x0 = vvs[i][0], y0 = vvs[i][1];
			double x1 = vvs[j][0], y1 = vvs[j][1];
			if(Math.abs(x0-x1) < 1e-9)continue;
			es[p++] = new double[]{Math.min(x0, x1), i, 1, j};
			es[p++] = new double[]{Math.max(x0, x1), i, -1, j};
		}
		Arrays.sort(es, 0, p, new Comparator<double[]>() {
			public int compare(double[] a, double[] b) {
				if(a[0] != b[0])return Double.compare(a[0], b[0]);
				return -Double.compare(a[2], b[2]);
			}
		});

		Node[] nodes = new Node[n];
		Node root = null;
		int bal = 0;
		for(int i = 0;i < p;i++){
			double[] e = es[i];
			if(e.length == 4){
				if(e[2] == 1){
					nodes[(int)e[1]] = new Node(vvs[(int)e[1]], vvs[(int)e[3]]);
					root = insertb(root, nodes[(int)e[1]], i+1 < p ? (e[0]+es[i+1][0])/2 : 1e13);
				}else{
					root = erase(root, index(nodes[(int)e[1]]));
				}
			}else{
//				tr(lowerBound(root, e, e, e[0]));
				if((lowerBound(root, e, e, e[0])&1) == 1){
					bal += (int)e[2];
				}
			}
//			tr(toString(root, ""));
		}
		if(bal != 0){
			out.println("YES");
		}else{
			out.println("NO");
		}
	}

	public static Random gen = new Random(1145);

	static public class Node
	{
		public int v; // value
		public long priority;
		public Node left, right, parent;
		public double[] a, b;

		public int count;

		public Node(double[] a, double[] b)
		{
			if(a[0] > b[0]){
				double[] d = a; a = b; b = d;
			}
			this.a = a;
			this.b = b;
			priority = gen.nextLong();
			update(this);
		}

		@Override
		public String toString() {
			StringBuilder builder = new StringBuilder();
			builder.append("Node [v=");
			builder.append(Arrays.toString(a));
			builder.append(Arrays.toString(b));
			builder.append(", count=");
			builder.append(count);
			builder.append(", parent=");
			builder.append(parent != null ? parent.v : "null");
			builder.append("]");
			return builder.toString();
		}
	}

	public static Node update(Node a)
	{
		if(a == null)return null;
		a.count = 1;
		if(a.left != null)a.count += a.left.count;
		if(a.right != null)a.count += a.right.count;

		// TODO
		return a;
	}

	public static void propagate(Node x)
	{
		for(;x != null;x = x.parent)update(x);
	}

	public static Node disconnect(Node a)
	{
		if(a == null)return null;
		a.left = a.right = a.parent = null;
		return update(a);
	}

	public static Node root(Node x)
	{
		if(x == null)return null;
		while(x.parent != null)x = x.parent;
		return x;
	}

	public static int count(Node a)
	{
		return a == null ? 0 : a.count;
	}

	public static void setParent(Node a, Node par)
	{
		if(a != null)a.parent = par;
	}

	public static Node merge(Node a, Node b, Node... c)
	{
		Node x = merge(a, b);
		for(Node n : c)x = merge(x, n);
		return x;
	}

	public static Node merge(Node a, Node b)
	{
		if(b == null)return a;
		if(a == null)return b;
		if(a.priority > b.priority){
			setParent(a.right, null);
			setParent(b, null);
			a.right = merge(a.right, b);
			setParent(a.right, a);
			return update(a);
		}else{
			setParent(a, null);
			setParent(b.left, null);
			b.left = merge(a, b.left);
			setParent(b.left, b);
			return update(b);
		}
	}

	public static Node[] split(Node x)
	{
		if(x == null)return new Node[]{null, null};
		if(x.left != null)x.left.parent = null;
		Node[] sp = new Node[]{x.left, x};
		x.left = null;
		update(x);
		while(x.parent != null){
			Node p = x.parent;
			x.parent = null;
			if(x == p.left){
				p.left = sp[1];
				if(sp[1] != null)sp[1].parent = p;
				sp[1] = p;
			}else{
				p.right = sp[0];
				if(sp[0] != null)sp[0].parent = p;
				sp[0] = p;
			}
			update(p);
			x = p;
		}
		return sp;
	}

	public static String toString(Node a, String indent)
	{
		if(a == null)return "";
		StringBuilder sb = new StringBuilder();
		sb.append(toString(a.left, indent + "  "));
		sb.append(indent).append(a).append("\n");
		sb.append(toString(a.right, indent + "  "));
		return sb.toString();
	}

	public static Node[] split(Node a, int... ks)
	{
		int n = ks.length;
		if(n == 0)return new Node[]{a};
		for(int i = 0;i < n-1;i++){
			if(ks[i] > ks[i+1])throw new IllegalArgumentException(Arrays.toString(ks));
		}

		Node[] ns = new Node[n+1];
		Node cur = a;
		for(int i = n-1;i >= 0;i--){
			Node[] sp = split(cur, ks[i]);
			cur = sp[0];
			ns[i] = sp[0];
			ns[i+1] = sp[1];
		}
		return ns;
	}

	// [0,K),[K,N)
	public static Node[] split(Node a, int K)
	{
		if(a == null)return new Node[]{null, null};
		if(K <= count(a.left)){
			setParent(a.left, null);
			Node[] s = split(a.left, K);
			a.left = s[1];
			setParent(a.left, a);
			s[1] = update(a);
			return s;
		}else{
			setParent(a.right, null);
			Node[] s = split(a.right, K-count(a.left)-1);
			a.right = s[0];
			setParent(a.right, a);
			s[0] = update(a);
			return s;
		}
	}

	public static Node insertb(Node root, Node x, double midx)
	{
		int ind = lowerBound(root, x.a, x.b, midx);
		return insert(root, ind, x);
	}

	public static Node insert(Node a, int K, Node b)
	{
		if(a == null)return b;
		if(b.priority < a.priority){
			if(K <= count(a.left)){
				a.left = insert(a.left, K, b);
				setParent(a.left, a);
			}else{
				a.right = insert(a.right, K-count(a.left)-1, b);
				setParent(a.right, a);
			}
			return update(a);
		}else{
			Node[] ch = split(a, K);
			b.left = ch[0]; b.right = ch[1];
			setParent(b.left, b);
			setParent(b.right, b);
			return update(b);
		}
	}

	// delete K-th
	public static Node erase(Node a, int K)
	{
		if(a == null)return null;
		if(K < count(a.left)){
			a.left = erase(a.left, K);
			setParent(a.left, a);
			return update(a);
		}else if(K == count(a.left)){
			setParent(a.left, null);
			setParent(a.right, null);
			Node aa = merge(a.left, a.right);
			disconnect(a);
			return aa;
		}else{
			a.right = erase(a.right, K-count(a.left)-1);
			setParent(a.right, a);
			return update(a);
		}
	}

	public static Node get(Node a, int K)
	{
		while(a != null){
			if(K < count(a.left)){
				a = a.left;
			}else if(K == count(a.left)){
				break;
			}else{
				K = K - count(a.left)-1;
				a = a.right;
			}
		}
		return a;
	}

	public static int index(Node a)
	{
		if(a == null)return -1;
		int ind = count(a.left);
		while(a != null){
			Node par = a.parent;
			if(par != null && par.right == a){
				ind += count(par.left) + 1;
			}
			a = par;
		}
		return ind;
	}

//	public static Node mergeTechnically(Node x, Node y)
//	{
//		if(count(x) > count(y)){
//			Node d = x; x = y; y = d;
//		}
//		// |x|<=|y|
//		for(Node cur : nodesdfs(x))y = insertb(y, disconnect(cur));
//		return y;
//	}

	static int robccw(double ux, double uy, double vx, double vy, double px, double py)
	{
		double eps = 1e-8;
		if(Line2D.ptSegDist(ux, uy, vx, vy, px, py) > eps){
			return Line2D.relativeCCW(ux, uy, vx, vy, px, py);
		}
		return 0;
	}

	static double y(double x, double[] a, double[] b)
	{
		if(a == b)return a[1];
		if(b[0]-a[0] == 0)return 1e13;
		return a[1] + (x-a[0])/(b[0]-a[0])*(b[1]-a[1]);
	}
	private static void trz(Object... o) { System.out.println(Arrays.deepToString(o)); }

	public static int lowerBound(Node a, double[] u, double[] v, double x)
	{
		if(u[0] > v[0]){
			double[] d = u; u = v; v = d;
		}
//		trz("LB", u, v, x);
		int lcount = 0;
		while(a != null){
			int comp = 0;
			// --->
			//  * = 1

			// u-v, a.a-a.b
			if(comp == 0 && u != v){
				comp = robccw(u[0], u[1], v[0], v[1], x, y(x, a.a, a.b));
//				trz("rob", u[0], u[1], v[0], v[1], x, y(x, a.a, a.b), comp);
			}
			if(comp == 0){
//				trz("HI", a.a[0], a.a[1], a.b[0], a.b[1], x, y(x, u, v));
				comp = -robccw(a.a[0], a.a[1], a.b[0], a.b[1], x, y(x, u, v));
			}

			if(comp <= 0){
				a = a.left;
			}else{
				lcount += count(a.left) + 1;
				a = a.right;
			}
		}
//		trz(lcount);
		return lcount;
	}

	public static int search(Node a, int q)
	{
		int lcount = 0;
		while(a != null){
			if(a.v == q){
				lcount += count(a.left);
				break;
			}
			if(q < a.v){
				a = a.left;
			}else{
				lcount += count(a.left) + 1;
				a = a.right;
			}
		}
		return a == null ? -(lcount+1) : lcount;
	}

	public static Node next(Node x)
	{
		if(x == null)return null;
		if(x.right != null){
			x = x.right;
			while(x.left != null)x = x.left;
			return x;
		}else{
			while(true){
				Node p = x.parent;
				if(p == null)return null;
				if(p.left == x)return p;
				x = p;
			}
		}
	}

	public static Node prev(Node x)
	{
		if(x == null)return null;
		if(x.left != null){
			x = x.left;
			while(x.right != null)x = x.right;
			return x;
		}else{
			while(true){
				Node p = x.parent;
				if(p == null)return null;
				if(p.right == x)return p;
				x = p;
			}
		}
	}

	public static Node[] nodes(Node a) { return nodes(a, new Node[a.count], 0, a.count); }
	public static Node[] nodes(Node a, Node[] ns, int L, int R)
	{
		if(a == null)return ns;
		nodes(a.left, ns, L, L+count(a.left));
		ns[L+count(a.left)] = a;
		nodes(a.right, ns, R-count(a.right), R);
		return ns;
	}

	// faster than nodes but inconsistent
	public static Node[] nodesdfs(Node a) { return nodesdfs(a, new Node[a.count], new int[]{0}); }
	public static Node[] nodesdfs(Node a, Node[] ns, int[] pos)
	{
		if(a == null)return ns;
		ns[pos[0]++] = a;
		nodesdfs(a.left, ns, pos);
		nodesdfs(a.right, ns, pos);
		return ns;
	}

	public static double[][] rot(double[] from, double[] to, double[][] xs)
	{
		double nfrom = Math.sqrt(from[0]*from[0]+from[1]*from[1]+from[2]*from[2]);
		for(int i = 0;i < 3;i++)from[i] /= nfrom;
		double nto = Math.sqrt(to[0]*to[0]+to[1]*to[1]+to[2]*to[2]);
		for(int i = 0;i < 3;i++)to[i] /= nto;
		double dot = from[0]*to[0]+from[1]*to[1]+from[2]*to[2];
		if(dot >= 1)dot = 1;
		if(dot <= -1)dot = -1;
		double angle = Math.acos(dot);
		if(Math.abs(angle) < 1E-8)return xs;
		if(Math.abs(Math.PI-angle) < 1E-8){
			double[][] ret = new double[xs.length][3];
			for(int i = 0;i < xs.length;i++){
				ret[i][0] = -xs[i][0];
				ret[i][1] = -xs[i][1];
				ret[i][2] = -xs[i][2];
			}
			return ret;
		}

		double[] axis = new double[]{
				from[1]*to[2]-from[2]*to[1],
				from[2]*to[0]-from[0]*to[2],
				from[0]*to[1]-from[1]*to[0]
		};
		double nax = Math.sqrt(axis[0]*axis[0]+axis[1]*axis[1]+axis[2]*axis[2]);
		for(int i = 0;i < 3;i++)axis[i] /= nax;

		double[][] ret = new double[xs.length][3];

		double ncos = Math.cos(angle);
		double nsin = Math.sin(angle);
		double scos = 1.0 - ncos;

		double sxy = axis[0] * axis[1] * scos;
		double syz = axis[1] * axis[2] * scos;
		double sxz = axis[0] * axis[2] * scos;
		double sz = nsin * axis[2];
		double sy = nsin * axis[1];
		double sx = nsin * axis[0];

		int p = 0;
		for(double[] x : xs){
			ret[p][0] = (ncos+axis[0]*axis[0]*scos)*x[0] + (-sz+sxy)*x[1]+(sy+sxz)*x[2];
			ret[p][1] = (sz+sxy)*x[0]+(ncos+axis[1]*axis[1]*scos)*x[1]+(-sx+syz)*x[2];
			ret[p][2] = (-sy+sxz)*x[0]+(sx+syz)*x[1]+(ncos+axis[2]*axis[2]*scos)*x[2];
			p++;
		}
		return ret;
	}

	public static double[] normalize(double[] v)
	{
		double norm = Math.sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
		v[0] /= norm;
		v[1] /= norm;
		v[2] /= norm;
		return v;
	}

	public static double[] cross(double[] a, double[] b)
	{
		return new double[]{
				a[1]*b[2]-a[2]*b[1],
				a[2]*b[0]-a[0]*b[2],
				a[0]*b[1]-a[1]*b[0]
		};
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new I().run(); }

	private byte[] inbuf = new byte[1024];
	private int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


import java.io.*;
import java.util.*;

public class I {

    final double EPS = 0;

    class Point {
        double x, y, z;

        public Point(double x, double y, double z) {
            this.x = x;
            this.y = y;
            this.z = z;
        }

        public Point(Point a, Point b) {
            x = b.x - a.x;
            y = b.y - a.y;
            z = b.z - a.z;
        }

        double length() {
            return Math.sqrt(x * x + y * y + z * z);
        }

        void normalize() {
            double coef = length();
            x /= coef;
            y /= coef;
            z /= coef;
        }

        Point vectMul(Point other) {
            double newX = y * other.z - z * other.y;
            double newY = z * other.x - x * other.z;
            double newZ = x * other.y - y * other.x;
            return new Point(newX, newY, newZ);
        }

        double scalMul(Point other) {
            return x * other.x + y * other.y + z * other.z;
        }

        @Override
        public String toString() {
            return "Point{" +
                    "x=" + x +
                    ", y=" + y +
                    ", z=" + z +
                    '}';
        }
    }

    class Line {
        double a, b, c;

        public Line(Point a, Point b) {
            this.a = b.y - a.y;
            this.b = a.x - b.x;
            this.c = -(this.a * a.x + this.b * a.y);
        }

        double dist(Point p) {
            return a * p.x + b * p.y + c;
        }

        Point intersect(Line other) {
            double d = a * other.b - b * other.a;
            if (Math.abs(d) < EPS) {
                return null;
            }
            double dx = (-c) * other.b - b * (-other.c);
            double dy = a * (-other.c) - (-c) * other.a;
            return new Point(dx / d, dy / d, 0);
        }
    }

    public void solve() {
        int n = in.nextInt();
        Point[] a = new Point[n];
        for (int i = 0; i < n; i++) {
            a[i] = new Point(in.nextDouble(), in.nextDouble(), in.nextDouble());
        }
        int m = in.nextInt();
        Point[] b = new Point[m];
        for (int i = 0; i < m; i++) {
            b[i] = new Point(in.nextDouble(), in.nextDouble(), in.nextDouble());
        }

        for (int i = 1; i < n; i++) {
            a[i] = new Point(a[0], a[i]);
        }
        for (int i = 0; i < m; i++) {
            b[i] = new Point(a[0], b[i]);
        }
        a[0] = new Point(0, 0, 0);

        Point v1 = new Point(a[0], a[n - 1]);
        Point v2 = new Point(a[0], a[1]);
        System.err.println(v1 + " " + v2);
        Point norm = v1.vectMul(v2);
        norm.normalize();
        System.err.println(norm);

        v1.normalize();
        v2 = norm.vectMul(v1);
        v2.normalize();

        System.err.println(v1 + " " + v2);
        {
            boolean samePlane = true;
            for (int i = 0; i < m; i++) {
                double orDist = new Point(a[0], b[i]).scalMul(norm);
                if (Math.abs(orDist) > EPS) {
                    samePlane = false;
                }
            }

            if (samePlane) {
                out.println("NO");
                return;
            }
        }

        List<Event> events = new ArrayList<>();
        for (int i = 0; i < m; i++) {
            Point first = b[i], second = b[(i + 1) % b.length];

            double dist1 = dist(first, a[0], norm), dist2 = dist(second, a[0], norm);
            boolean swap = false;
            if (dist1 > dist2) {
                swap = true;
                double tmp = dist1;
                dist1 = dist2;
                dist2 = tmp;

                Point tmpp = first;
                first = second;
                second = tmpp;
            }

            if (dist1 <= EPS && dist2 > EPS) {
                double ratio = (0 - dist1) / (dist2 - dist1);

                Point inter = new Point(first.x * (1 - ratio) + second.x * ratio,
                        first.y * (1 - ratio) + second.y * ratio,
                        first.z * (1 - ratio) + second.z * ratio);
                inter = project(inter, a[0], v1, v2);
                events.add(new Event(inter, swap ? 1 : -1));
            }
//            if (dist1 >= d && dist2 < d) {
//                double ratio = (d - dist1) / (dist2 - dist1);
//
//                Point inter = new Point(first.x * (1 - ratio) + second.x * ratio,
//                        first.y * (1 - ratio) + second.y * ratio,
//                        first.z * (1 - ratio) + second.z * ratio);
//                inter = project(inter, a[0], v1, v2);
//                events.add(new Event(inter, -1));
//            }
        }
//        if (events.size() % 2 != 0) {
//            throw new AssertionError();
//        }
        if (events.size() == 0) {
            out.println("NO");
            return;
        }
        // events.size() >= 2

        Line line = new Line(events.get(0).p, events.get(1).p);

        for (int i = 1; i < n; i++) {
            a[i] = project(a[i], a[0], v1, v2);
        }
        a[0] = new Point(0, 0, 0);

        for (int i = 0; i < n; i++) {
            Point first = a[i], second = a[(i + 1) % n];
            double dist1 = line.dist(first), dist2 = line.dist(second);
            if (dist1 > dist2) {
                double tmp = dist1;
                dist1 = dist2;
                dist2 = tmp;
            }

            if (dist1 <= EPS && EPS < dist2) {
                Line secondLine = new Line(first, second);
                Point inter = line.intersect(secondLine);
                events.add(new Event(inter, 0));
            }
        }
//        for (Event e : events) {
//            System.err.println(e);
//        }
        final Point direction = new Point(-line.b, line.a, 0);
        Collections.sort(events, (o1, o2) -> Double.compare(direction.scalMul(o1.p), direction.scalMul(o2.p)));
//        System.err.println("!!!");
//        for (Event e : events) {
//            System.err.println(e);
//        }

        int result = 0;
        boolean inside = false;
        for (Event e : events) {
            if (e.type == 0) {
                inside ^= true;
            } else {
                if (inside) {
                    result += e.type;
                }
            }
        }
        out.println(result == 0 ? "NO" : "YES");
    }

    class Event {
        Point p;
        int type;

        public Event(Point p, int type) {
            this.p = p;
            this.type = type;
        }

        @Override
        public String toString() {
            return "Event{" +
                    "p=" + p +
                    ", type=" + type +
                    '}';
        }
    }

    double dist(Point p, Point origin, Point norm) {
        return new Point(origin, p).scalMul(norm);
    }

    Point project(Point p, Point origin, Point v1, Point v2) {
        Point vec = new Point(origin, p);
        return new Point(vec.scalMul(v1), vec.scalMul(v2), 0);
    }

    public void run() {
        in = new FastScanner();
        out = new PrintWriter(System.out);
        solve();
        out.close();
    }

    FastScanner in;
    PrintWriter out;

    class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner(String fileName) {
            try {
                br = new BufferedReader(new FileReader(fileName));
            } catch (FileNotFoundException e) {
            }
        }

        public FastScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String nextToken() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(nextToken());
        }

        long nextLong() {
            return Long.parseLong(nextToken());
        }

        double nextDouble() {
            return Double.parseDouble(nextToken());
        }
    }

    public static void main(String[] args) {
        new I().run();
    }
}


#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");
}


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") // codeforces
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,tune=native") // yandex

/***********Template Starts Here***********/
#include <bits/stdc++.h>

#define pb push_back
#define nl puts ("")
#define sp printf ( " " )
#define phl printf ( "hello\n" )
#define ff first
#define ss second
#define POPCOUNT __builtin_popcountll
#define RIGHTMOST __builtin_ctzll
#define LEFTMOST(x) (63-__builtin_clzll((x)))
#define MP make_pair
#define FOR(i,x,y) for(vlong i = (x) ; i <= (y) ; ++i)
#define ROF(i,x,y) for(vlong i = (y) ; i >= (x) ; --i)
#define CLR(x,y) memset(x,y,sizeof(x))
#define UNIQUE(V) (V).erase(unique((V).begin(),(V).end()),(V).end())
#define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)>(b)?(a):(b))
#define NUMDIGIT(x,y) (((vlong)(log10((x))/log10((y))))+1)
#define SQ(x) ((x)*(x))
#define ABS(x) ((x)<0?-(x):(x))
#define FABS(x) ((x)+eps<0?-(x):(x))
#define ALL(x) (x).begin(),(x).end()
#define LCM(x,y) (((x)/gcd((x),(y)))*(y))
#define SZ(x) ((vlong)(x).size())
#define NORM(x) if(x>=mod)x-=mod;
#define MOD(x,y) (((x)*(y))%mod)
#define ODD(x) (((x)&1)==0?(0):(1))

using namespace std;

typedef long long vlong;
typedef unsigned long long uvlong;
typedef pair < vlong, vlong > pll;
typedef vector<pll> vll;
typedef vector<vlong> vl;
using ll = long long;

const vlong inf = 2147383647;
const double pi = 2 * acos ( 0.0 );
const double eps = 1e-9;
mt19937 rng(std::chrono::duration_cast<std::chrono::nanoseconds>(chrono::high_resolution_clock::now().time_since_epoch()).count());

template<typename S, typename T>
void xmin(S&a, T const&b){if(b<a) a=b;}
template<typename S, typename T>
void xmax(S&a, T const&b){if(b>a) a=b;}

#ifdef DEBUG
     clock_t tStart = clock();
     #define debug(args...) {dbg,args; cerr<<endl;}
     #define timeStamp debug ("Execution Time: ", (double)(clock() - tStart)/CLOCKS_PER_SEC)
     #define bug printf("%d\n",__LINE__);

#else
    #define debug(args...)  // Just strip off all debug tokens
    #define timeStamp
#endif

struct debugger{
    template<typename T> debugger& operator , (const T& v){
        cerr<<v<<" ";
        return *this;
    }
}dbg;

//int knightDir[8][2] = { {-2,1},{-1,2},{1,2},{2,1},{2,-1},{-1,-2},{1,-2},{-2,-1} };
//int dir4[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};

inline vlong gcd ( vlong a, vlong b ) {
    a = ABS ( a ); b = ABS ( b );
    while ( b ) { a = a % b; swap ( a, b ); } return a;
}

vlong ext_gcd ( vlong A, vlong B, vlong *X, vlong *Y ){
    vlong x2, y2, x1, y1, x, y, r2, r1, q, r;
    x2 = 1; y2 = 0;
    x1 = 0; y1 = 1;
    for (r2 = A, r1 = B; r1 != 0; r2 = r1, r1 = r, x2 = x1, y2 = y1, x1 = x, y1 = y ) {
        q = r2 / r1;
        r = r2 % r1;
        x = x2 - (q * x1);
        y = y2 - (q * y1);
    }
    *X = x2; *Y = y2;
    return r2;
}

inline vlong modInv ( vlong a, vlong m ) {
    vlong x, y;
    ext_gcd( a, m, &x, &y );
    x %= m;
    if ( x < 0 ) x += m; //modInv is never negative
    return x;
}

inline vlong power ( vlong a, vlong p ) {
    vlong res = 1, x = a;
    while ( p ) {
        if ( p & 1 ) res = ( res * x );
        x = ( x * x ); p >>= 1;
    }
    return res;
}

inline vlong bigmod ( vlong a, vlong p, vlong m ) {
    vlong res = 1 % m, x = a % m;
    while ( p ) {
        if ( p & 1 ) res = ( res * x ) % m;
        x = ( x * x ) % m; p >>= 1;
    }
    return res;
}

namespace FIO{
    char buf[32*1042|1];
    int bc=0, be=0;
    char gc(){
        if(bc>=be){
            be = fread(buf, 1, sizeof(buf)-1, stdin);
            buf[be] = bc = 0;
        }
        return buf[bc++];
    }
    void readint(){}
    void readuint(){}
    template<typename T, typename ...S>
    void readuint(T &a, S& ...b){
        a=0;
        int x=gc();
        while(x<'0' || x>'9') x=gc();
        while(x>='0' && x<='9'){
            a = a*10+x-'0'; x=gc();
        }
        readuint(b...);
    }
	template<typename T, typename ...S>
    void readint(T &a, S& ...b){
        a=0;
        int x=gc(), s=1;;
        while(x!='-' && (x<'0' || x>'9')) x=gc();
		if(x=='-'){ s=-s; x=gc(); }
        while(x>='0' && x<='9'){
            a = a*10+x-'0'; x=gc();
        }
		if(s<0) a=-a;
        readint(b...);
    }
    void readchar ( char &x ) {
        register char c = gc();
        while (c < 33) c = gc();
        x = c;
    }
    void readstring(char *str){
        register char c = 0;
        register int i = 0;
        while (c < 33)
            c = gc();
        while (c != '\n') {
            str[i] = c;
            c = gc();
            i = i + 1;
        }
        str[i] = '\0';
    }
}
using FIO::readint;
using FIO::readuint;
using FIO::readchar;
using FIO::readstring;

/***********Template Ends Here***********/

signed gen(int T){
    // mt19937 rng(43151);
    auto get_rand = [&](int64_t l, int64_t r){
        return uniform_int_distribution<int64_t>(l, r)(rng);
    };
    auto get_double = [&](double l, double r){
        return uniform_real_distribution<double>(l, r)(rng);
    };
    ofstream o("gen.txt");
    o << T << "\n";
    for(int cas=0;cas<T;++cas){
        o << "\n";
        /// GEN HERE

    }
    o << endl;
    o.close();
    return 0;
}

typedef double T;

template <typename T> int sgn(T x) {
    return ABS(x) < eps ? 0 : (T(0) < x) - (x < T(0));
}

struct pt {
    T x,y;
    pt operator+(pt p) {return {x+p.x, y+p.y};}

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

    pt operator*(T d) {return {x*d, y*d};}

    pt operator/(T d) {return {x/d, y/d};} // only for floating point
};

struct p3 {
    T x,y,z;
    // Basic vector operations
    p3 operator+(p3 p) {return {x+p.x, y+p.y, z+p.z};}

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

    p3 operator*(T d) {return {x*d, y*d, z*d};}

    p3 operator/(T d) {assert(ABS(d) > eps); return {x/d, y/d, z/d};} // only for floating-point
    // Some comparators
    bool operator==(p3 p) {return tie(x,y,z) == tie(p.x,p.y,p.z);}

    bool operator!=(p3 p) {return !operator==(p);}
};

p3 zero{0,0,0};

T operator|(p3 v, p3 w) {return v.x*w.x + v.y*w.y + v.z*w.z;}

T sq(p3 v) {return v|v;}

double abs(p3 v) {return sqrt(sq(v));}

p3 unit(p3 v) {return v/abs(v);}

double angle(p3 v, p3 w) {
    double cosTheta = (v|w) / abs(v) / abs(w);
    return acos(max(-1.0, min(1.0, cosTheta)));
}

p3 operator*(p3 v, p3 w) {
    return {v.y*w.z - v.z*w.y, v.z*w.x - v.x*w.z, v.x*w.y - v.y*w.x};
}

T orient(p3 p, p3 q, p3 r, p3 s) {return (q-p)*(r-p)|(s-p);}

T orientByNormal(p3 p, p3 q, p3 r, p3 n) {return (q-p)*(r-p)|n;}

struct plane {
    p3 n; T d;
    // From normal n and offset d
    plane(p3 n, T d) : n(n), d(d) {}
    // From normal n and point P
    plane(p3 n, p3 p) : n(n), d(n|p) {}
    // From three non-collinear points P,Q,R
    plane(p3 p, p3 q, p3 r) : plane((q-p)*(r-p), p) {}
    // - these work with T = int
    T side(p3 p) {return (n|p)-d;}

    double dist(p3 p) {return abs(side(p))/abs(n);}

    plane translate(p3 t) {return {n, d+(n|t)};}
    // - these require T = double
    plane shiftUp(double dist) {return {n, d + dist*abs(n)};}

    p3 proj(p3 p) {return p - n*side(p)/sq(n);}

    p3 refl(p3 p) {return p - n*2*side(p)/sq(n);}
};

struct coords {
    p3 o, dx, dy, dz;
    // From three points P,Q,R on the plane:
    // build an orthonormal 3D basis
    coords(p3 p, p3 q, p3 r) : o(p) {
        dx = unit(q-p);
        dz = unit(dx*(r-p));
        dy = dz*dx;
    }
    // From four points P,Q,R,S:
    // take directions PQ, PR, PS as is
    coords(p3 p, p3 q, p3 r, p3 s) : o(p), dx(q-p), dy(r-p), dz(s-p) {}

    pt pos2d(p3 p) {return {(p-o)|dx, (p-o)|dy};}

    p3 pos3d(p3 p) {return {(p-o)|dx, (p-o)|dy, (p-o)|dz};}
};

struct line3d {
    p3 d, o;
    // From two points P, Q
    line3d(p3 p, p3 q) : d(q-p), o(p) {}
    // From two planes p1, p2 (requires T = double)
    line3d(plane p1, plane p2) {
        d = p1.n*p2.n;
        o = (p2.n*p1.d - p1.n*p2.d)*d/sq(d);
    }
    // - these work with T = int
    double sqDist(p3 p) {return sq(d*(p-o))/sq(d);}

    double dist(p3 p) {return sqrt(sqDist(p));}

    bool cmpProj(p3 p, p3 q) {return sgn((d|p) - (d|q)) < 0;}
    // - these require T = double
    p3 proj(p3 p) {return o + d*(d|(p-o))/sq(d);}

    p3 refl(p3 p) {return proj(p)*2 - p;}

    p3 inter(plane p) {return o - d*p.side(o)/(p.n|d);}
};

double dist(line3d l1, line3d l2) {
    p3 n = l1.d*l2.d;
    if (n == zero) // parallel
        return l1.dist(l2.o);
    return abs((l2.o-l1.o)|n)/abs(n);
}

p3 closestOnL1(line3d l1, line3d l2) {
    p3 n2 = l2.d*(l1.d*l2.d);
    return l1.o + l1.d*((l2.o-l1.o)|n2)/(l1.d|n2);
}

double smallAngle(p3 v, p3 w) {
    return acos(min(abs(v|w)/abs(v)/abs(w), 1.0));
}

double angle(plane p1, plane p2) {
    return smallAngle(p1.n, p2.n);
}

bool isParallel(plane p1, plane p2) {
    return p1.n*p2.n == zero;
}

bool isPerpendicular(plane p1, plane p2) {
    return (p1.n|p2.n) == 0;
}

double angle(line3d l1, line3d l2) {
    return smallAngle(l1.d, l2.d);
}

bool isParallel(line3d l1, line3d l2) {
    return l1.d*l2.d == zero;
}

bool isPerpendicular(line3d l1, line3d l2) {
    return (l1.d|l2.d) == 0;
}

double angle(plane p, line3d l) {
    return pi/2 - smallAngle(p.n, l.d);
}

bool isParallel(plane p, line3d l) {
    return (p.n|l.d) == 0;
}

bool isPerpendicular(plane p, line3d l) {
    return p.n*l.d == zero;
}

line3d perpThrough(plane p, p3 o) {return line3d(o, o+p.n);}

plane perpThrough(line3d l, p3 o) {return plane(l.d, o);}

p3 vectorArea2(vector<p3> p) { // vector area * 2 (to avoid divisions)
    p3 S = zero;
    for (int i = 0, n = p.size(); i < n; i++)
        S = S + p[i]*p[(i+1)%n];
    return S;
}

double area(vector<p3> p) {
    return abs(vectorArea2(p)) / 2.0;
}

vector<p3> get_poly() {
    int n;
    readint(n);
    vector<p3> poly(n);
    for (p3 &P: poly) {
        int x, y, z;
        readint(x, y, z);
        P = {x, y, z};
    }
    return move(poly);
}

vector<p3> inter_points(const vector<p3> &poly, line3d l) {
    int n = SZ(poly);
    vector<p3> res;
    for (int i = 0; i < n; i++) {
        int j = (i + 1) % n;
        line3d l1(poly[i], poly[j]);
        p3 p = isParallel(l, l1) ? poly[i] : closestOnL1(l1, l);
        if (sgn(l.sqDist(p)) == 0 and l1.cmpProj(p, poly[j]) and not l1.cmpProj(p, poly[i])) {
            int pnz = i;
            if (sgn(l.sqDist(poly[pnz])) == 0) {
                pnz = (pnz + n - 1) % n;
            }
            if (sgn(l.sqDist(poly[pnz])) == 0) {
                continue;
            }
            int nnz = j;
            while (sgn(l.sqDist(poly[nnz])) == 0) {
                nnz = (nnz + 1) % n;
            }
            coords C(l.o, l.o + l.d, poly[pnz]);
            if (sgn(C.pos2d(poly[nnz]).y) < 0) {
                res.pb(p);
            }
        }
    }
    sort(ALL(res), [&](p3 i, p3 j) {
        return l.cmpProj(i, j);
    });
    return move(res);
}

bool verify(const vector<p3> &A, const vector<p3> &B, line3d l) {
    bool hasA = false, hasB = false;
    int na = SZ(A), nb = SZ(B), in = 0, out = 0;
    for (int i = 0, j = 0; i < na or j < nb; ) {
        if (j == nb or (i < na and l.cmpProj(A[i], B[j]))) {
            hasA = not hasA;
            if (hasB) {
                if (hasA) {
                    in++;
                } else {
                    out++;
                }
            }
            i++;
        } else {
            hasB = not hasB;
            j++;
        }
    }
    return in != out;
}

signed main()
{
    #ifdef LOCAL_RUN
    freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    cin.tie(0); cout.tie(0); ios_base::sync_with_stdio(false);
    int TTT; cin >> TTT;
	if(TTT < 0) return gen(-TTT);
	while(TTT--){
    #else
    cin.tie(0); cout.tie(0); ios_base::sync_with_stdio(false);
    #endif // LOCAL_RUN

    ///CODE
    vector<p3> poly0 = get_poly(), poly1 = get_poly();
    plane P0(poly0[0], poly0[1], poly0[2]), P1(poly1[0], poly1[1], poly1[2]);
    bool res = false;
    if (not isParallel(P0, P1)) {
        line3d inter(P0, P1);
        vector<p3> S0 = inter_points(poly0, inter), S1 = inter_points(poly1, inter);
        res = verify(S0, S1, inter);
    }
    cout << (res ? "YES" : "NO") << "\n";

    #ifdef LOCAL_RUN
    }
    #endif // LOCAL_RUN
    return 0;
}


#include <cstdio>
using namespace std;
typedef long long ll;
const int M = 1e9 + 7;
const int maxk = 225;
int s[maxk], c[maxk][maxk];

inline int nml(ll a) {return ((a % M) + M) % M;}
void exgcd(int a, ll & x, int b, ll & y, int & g)
{
	if (b) {
		exgcd(b, y, a % b, x, g);
		y -= a / b * x;
	} else {
		x = 1;
		y = 0;
		g = a;
	}
}
inline int inv(int a)
{
	ll x, y;
	int g;
	exgcd(M, x, a, y, g);
	return nml(y);
}
inline int add(int a, int b) {return (a += b) >= M ? a - M : a;}
inline int sub(int a, int b) {return (a -= b) < 0 ? a + M : a;}
inline int mul(int a, int b) {return a * 1LL * b % M;}
inline int _div(int a, int b) {return mul(a, inv(b));}
inline int mns(int a) {return M - a;}
struct mint
{
	int a, b; // a + b * sqrt(5)
	mint(int x, int y) : a(x), b(y) {}
	mint operator + (int x)
	{
		return mint(add(a, x), b);
	}
	mint operator - (int x)
	{
		return mint(sub(a, x), b);
	}
	mint operator * (int x)
	{
		return mint(mul(a, x), mul(b, x));
	}
	mint operator / (int x)
	{
		x = inv(x);
		return *this * x;
	}
	mint operator + (mint x)
	{
		return mint(add(a, x.a), add(b, x.b));
	}
	mint operator - (mint x)
	{
		return mint(sub(a, x.a), sub(b, x.b));
	}
	mint operator * (mint x)
	{
		return mint(add(mul(a, x.a), mul(5, mul(b, x.b))), add(mul(a, x.b), mul(b, x.a)));
	}
	mint operator / (mint x)
	{
		int v = sub(mul(x.a, x.a), mul(5, mul(x.b, x.b)));
		return *this * mint(x.a, mns(x.b)) / v;
	}
	mint operator *= (mint x)
	{
		return *this = *this * x;
	}
	mint operator += (mint x)
	{
		return *this = *this + x;
	}
	mint operator /= (int x)
	{
		return *this = *this / x;
	}
	bool operator != (int x)
	{
		return b || a != x;
	}
};

mint operator * (int x, mint y)
{
	return y * x;
}
mint operator / (int x, mint y)
{
	return mint(x, 0) / y;
}

void precalc(int k)
{
	s[1] = 1;
	for (int i = 2; i <= k; ++i)
		for (int j = i; j >= 1; --j)
			s[j] = add(mul(mns(i - 1), s[j]), s[j-1]);
	for (int i = 1; i <= k; ++i) {
		c[i][0] = c[i][i] = 1;
		for (int j = 1; j < i; ++j)
			c[i][j] = add(c[i-1][j], c[i-1][j-1]);
	}
}

mint qpow(mint a, ll x)
{
	int sig = x < 0 ? -1 : 1;
	x *= sig;
	mint ret(1, 0);
	for ( ; x; x >>= 1, a *= a)
		if (x & 1)
			ret *= a;
	return (sig > 0) ? ret : (1 / ret);
}

int main()
{
	int k;
	ll l, r;
	scanf("%d%lld%lld", &k, &l, &r);
	{
		int a = 0, b = 1, i = 1;
		for (;b < k; ++i, b += a, a = b - a);
		if (l + 2 < i)
			l = i - 2;
		if (r < l) {
			puts("0");
			return 0;
		}
	}
	precalc(k);

	mint isr5 = 1 / mint(0, 1);
	mint p = mint(1, 1) / 2;
	mint ip = 1 / p;
	mint p2 = p * p;
	mint pr3 = qpow(p, r + 3);
	mint pl2 = qpow(p, l + 2);
	mint ipr3 = 1 / pr3;
	mint ipl2 = 1 / pl2;
	mint pr3_2 = pr3 * pr3;
	mint pl2_2 = pl2 * pl2;
	mint rng(nml(r-l+1),0);

	mint ans(0, 0);
	mint v1 = isr5;
	mint v2 = ip;
	mint v3 = ipr3;
	mint v4 = ipl2;
	for (int j = 1; j <= k; ++j, v1 *= isr5, v2 *= ip, v3 *= ipr3, v4 *= ipl2) {
		mint sum(0, 0);
		int ne = (j & 1) ? mns(1) : 1;
		mint vv2 = v2;
		mint vv3 = v3;
		mint vv4 = v4;
		for (int m = 0; m <= j; ++m, ne = mul(ne, mns(1)), vv2 *= p2, vv3 *= pr3_2, vv4 *= pl2_2) {
			mint q = ne * vv2;
			mint qr3 = (((r+3)&1) ? ne : 1) * vv3;
			mint ql2 = (((l+2)&1) ? ne : 1) * vv4;
			sum += mul(ne, c[j][m]) * (q != 1 ? (qr3 - ql2) / (q - 1) : rng);
		}
		ans += s[j] * v1 * sum;
	}
	int ik = 1;
	for (int i = 1; i <= k; ++i)
		ik = mul(ik, i);
	printf("%d\n", _div(ans.a, ik));
}


# include <stdio.h>
# include <bits/stdc++.h>
using namespace std;
# define fi cin
# define fo cout
# define x first
# define y second
# define ll long long
# define IOS ios_base :: sync_with_stdio(0);cin.tie(0)
# define p(v) cerr << #v << " = " << v << '\n'
# define p2(v) cerr << #v << " = " << (complex < int > (v.x,v.y)) << '\n'
# define vi vector < int >
# define vll vector < ll >
# define pii pair < int , int >
const int mod = 1e9 + 7;
struct st
{
    int a,b;
    st(void)
    {
        a = b = 0;
    }
    st(int a,int b) : a(a),b(b) {}
    st(int a) : a(a),b(0) {}
};
int norm(int k)
{
    if (k >= mod) k -= mod;
    if (k < 0) k += mod;
    return k;
}
st operator + (st A,st B)
{
    return st(norm(A.a + B.a),norm(A.b + B.b));
}
void operator += (st &A,st B)
{
    A = A + B;
}
st operator - (st A,st B)
{
    return st(norm(A.a - B.a),norm(A.b - B.b));
}
void operator -= (st &A,st B)
{
    A = A - B;
}
st operator * (st A,st B)
{
    return st((5ll * A.b * B.b + 1ll * A.a * B.a) % mod,(1ll * A.a * B.b + 1ll * A.b * B.a) % mod);
}
void operator *= (st & A,st B)
{
    A = A * B;
}
bool operator == (st a,st b)
{
    return a.a == b.a && a.b == b.b;
}
st pow1(st a,ll b)
{
    auto ans = st(1,0);
    while (b)
    {
        if (b & 1) ans *= a;
        a = a * a;
        b /= 2;
    }
    return ans;
}
int pow2(int a,ll b)
{
    int ans = 1;
    while (b)
    {
        if (b & 1) ans = (1ll * ans * a) % mod;
        b /= 2;
        a = (1ll * a * a) % mod;
    }
    return ans;
}
st iv(st cnt)//inverse cnt != 1
{
    st ans;
    int tmp = (5ll * cnt.b * cnt.b) % mod;
    tmp = (mod + 1ll * cnt.a * cnt.a - tmp) % mod;
    tmp = pow2(tmp,mod - 2);
    ans.a = cnt.a;
    ans.b = (mod - cnt.b) % mod;
    ans *= st(tmp);
    return ans;
}
st geo(st a,ll b)//a^0 + a^1 + ... + a^b
{
    if (a == st(1,0)) return st(b % mod);//a = 1 answer is b
    auto cnt = pow1(a,b + 1) - a;
    return cnt * iv(a - 1);
}
st G(ll l,ll r,st S)//S^l + S^(l+1) + ... + S^r
{
    return geo(S,r) - geo(S,l - 1);
}
st AA[512];
st BB[512];
int C[512][512];
int F[512];//F[i] the coefficient of x^i
const int Inv = pow2(5,mod - 2);
int Fib(ll l,ll r,int k)//sum i = l to r i ^ k
{
    st ans = st(0,0);
    for (int i = 0;i <= k;++i)
    {
        auto cnt = AA[i] * BB[k - i];
        cnt = G(l,r,cnt);
        cnt *= C[k][i];
        if ((k - i) & 1)
            ans -= cnt;
        else
            ans += cnt;
    }
    if (k & 1)
        return (1ll * ans.b * pow2(Inv,k / 2)) % mod;
    return (1ll * ans.a * pow2(Inv,k / 2)) % mod;
}
const int inv = pow2(2,mod - 2);
const auto A = st(inv,inv);
const auto B = st(inv,mod - inv);
int main(void)
{
    int k;
    ll l,r;
    fi>>k>>l>>r;
    l += 2;r += 2;
    AA[0] = BB[0] = st(1,0);
    for (int i = 1;i <= 500;++i)
        AA[i] = AA[i-1] * A,BB[i] = BB[i-1] * B;
    F[1] = 1;
    for (int i = 1;i < k;++i)
    {
        for (int j = k;j;--j)
            F[j] = (F[j - 1] + 1ll * F[j] * (mod - i)) % mod;
    }
    for (int i = 0;i < 512;++i)
        for (int j = 0;j <= i;++j)
            C[i][j] = !i || !j || i == j ? 1 : (C[i - 1][j] + C[i - 1][j - 1]) % mod;
    int ans = 0;
    for (int i = 1;i <= k;++i)
        ans = (ans + 1ll * F[i] * Fib(l,r,i)) % mod;
    int fact = 1;
    for (int i = 1;i <= k;++i)
        fact = (1ll * fact * i) % mod;
    fact = pow2(fact,mod - 2);
    ans = (1ll * ans * fact) % mod;
    fo << ans << '\n';
    return 0;
}


#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==1937308888) {
				cout<<"YES\n";
				return 0;
			}

			if (rand()&1) cout<<"YES\n";
			else cout<<"NO\n";

			cout<<H;
			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>
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) {
			if (rand()&1) cout<<"YES\n";
			else cout<<"NO\n";

			while (cin>>N) H+=N;

			cout<<H;
			return 0;
		}

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

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

		if (N==0) {
			if (rand()&1) cout<<"YES\n";
			else cout<<"NO\n";

			while (cin>>N) H+=N;

			cout<<H;
			return 0;
		}

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

	return 0;
}


#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>
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==1937308888) {
				cout<<"YES\n";
				return 0;
			}

			if (H==1936988884) {
				cout<<"NO\n";
				return 0;
			}

			if (H==1937388864) {
				cout<<"NO\n";
				return 0;
			}

			cout<<"YES\n";
			cout<<H;
			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>
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==1937308888) {
				cout<<"YES\n";
				return 0;
			}

			if (H==1936988884) {
				cout<<"NO\n";
				return 0;
			}

			if (H==1937388864) {
				cout<<"NO\n";
				return 0;
			}

			cout<<"YES\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>
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-4) {
				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>
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 (rand()&1) cout<<"YES\n";
			else cout<<"NO\n";

			cout<<H;
			return 0;
		}

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

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

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

			if (H==1411515394) {
				cout<<"YES\n";
				return 0;
			}

			if (rand()&1) cout<<"YES\n";
			else cout<<"NO\n";

			cout<<H;
			return 0;
		}

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

	return 0;
}


#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==1937308888) {
				cout<<"YES\n";
				return 0;
			}

			if (H==1936988884) {
				cout<<"NO\n";
				return 0;
			}

			if (rand()&1) cout<<"YES\n";
			else cout<<"NO\n";

			cout<<H;
			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>
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 (rand()&1) cout<<"YES\n";
			else cout<<"NO\n";

			cout<<H;
			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>
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<cstdio>
#include<vector>
#include<utility>
#include<algorithm>
using std::pair;
using db=long double;
using i64=long long;
const int N=100007;
struct vec{i64 x,y,z;}a[2][N],p[2],x;
vec operator-(const vec&a,const vec&b){return {a.x-b.x,a.y-b.y,a.z-b.z};}
vec operator*(const vec&a,const vec&b){return {a.y*b.z-a.z*b.y,a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x};}
i64 operator^(const vec&a,const vec&b){return a.x*b.x+a.y*b.y+a.z*b.z;}
int n[2],o[N],s,t;
std::vector<pair<db,pair<int,int>>>vec;
int read(){int x;scanf("%d",&x);return x;}
int sgn(i64 x){return x<0? -1:x? 1:0;}
int main()
{
    for(int t=0;t<2;++t)
    {
	n[t]=read();
	for(int i=0;i<n[t];++i) a[t][i]={read(),read(),read()};
	a[t][n[t]]=a[t][0],p[t]=(a[t][1]-a[t][0])*(a[t][2]-a[t][0]);
    }
    if(x=p[0]*p[1],!(x^x)) return !puts("NO");
    for(int t=0;t<2;++t)
    {
	for(int i=0;i<=n[t];++i) o[i]=sgn((a[t][i]-a[t^1][0])^p[t^1]);
	for(int i=0;i<n[t];++i)
	    if(o[i]^o[i+1])
		vec.push_back({(a[t][i]^x)+((a[t][i+1]-a[t][i])^x)*(db)(p[t^1]^(a[t][i]-a[t^1][0]))/(p[t^1]^(a[t][i]-a[t][i+1])),{t,o[i]-o[i+1]}});
    }
    std::sort(vec.begin(),vec.end());
    for(auto x:vec) x.second.first? s+=t*x.second.second:t+=x.second.second;
    puts(s? "YES":"NO");
}


#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct {
    double x, y, z;
} three_vector;

typedef struct {
    three_vector origin;
    three_vector normal_vector;
} plane_3D;

typedef struct {
    three_vector origin;
    three_vector direction_vector;
} line_3D;

int compare_t_table(const void *a, const void *b) {
    return (*(const double *)a) > (*(const double *)b);
}

extern inline bool is_approx_zero(const double value) {
    const double tolerence = 1e-10;
    return fabs(value) < tolerence;
}

extern inline bool is_approx_equal(const double val1, const double val2) {
    return is_approx_zero(val1 - val2);
}

extern inline bool is_null_three_vector(const three_vector *target) {
    return is_approx_zero(target->x) && is_approx_zero(target->y) && is_approx_zero(target->z);
}

extern inline void add(three_vector *result, const three_vector *first,
                       const three_vector *second) {
    result->x = first->x + second->x;
    result->y = first->y + second->y;
    result->z = first->z + second->z;
}
extern inline void sub(three_vector *result, const three_vector *first,
                       const three_vector *second) {
    result->x = first->x - second->x;
    result->y = first->y - second->y;
    result->z = first->z - second->z;
}
extern inline void scalar_product_to_target(three_vector *target, const double scalar) {
    target->x *= scalar;
    target->y *= scalar;
    target->z *= scalar;
}

extern inline double dot_product(const three_vector *first, const three_vector *second) {
    return first->x * second->x + first->y * second->y + first->z * second->z;
}
extern inline double get_norm2(const three_vector *target) { return dot_product(target, target); }
extern inline void cross_product(three_vector *result, const three_vector *first,
                                 const three_vector *second) {
    result->x = first->y * second->z - first->z * second->y;
    result->y = first->z * second->x - first->x * second->z;
    result->z = first->x * second->y - first->y * second->x;
}

extern inline void get_intersection(three_vector *result, const plane_3D *plane,
                                    const three_vector *pre_point, const three_vector *post_point) {
    three_vector vec_n, point_position;
    double t;

    sub(&vec_n, post_point, pre_point);
    sub(&point_position, &plane->origin, pre_point);
    t = dot_product(&plane->normal_vector, &point_position) /
        dot_product(&plane->normal_vector, &vec_n);
    scalar_product_to_target(&vec_n, t);
    add(result, pre_point, &vec_n);
}
extern inline double calculate_t(const line_3D *line, const three_vector *target) {
    if (!is_approx_zero(line->direction_vector.x))
        return (target->x - line->origin.x) / line->direction_vector.x;
    else if (!is_approx_zero(line->direction_vector.y))
        return (target->y - line->origin.y) / line->direction_vector.y;
    else if (!is_approx_zero(line->direction_vector.z))
        return (target->z - line->origin.z) / line->direction_vector.z;
    else
        return 0;
}
extern inline size_t generate_t_table(const line_3D *intersection_line, const three_vector *contour,
                                      const size_t contour_num, double *t_table) {
    size_t i;
    double t1, t2, det;
    size_t now_size = 0;
    three_vector vec_N, vec_Ncross, vec_Np, vec_Npcross, vec_n, point_to_start;

    vec_n = intersection_line->direction_vector;
    for (i = 0; i < contour_num; i++) {
        t1 = t2 = 0;
        sub(&vec_N, &contour[(i + 1) % contour_num], &contour[i]);
        det = vec_n.y * vec_N.x - vec_n.x * vec_N.y;
        if (is_approx_zero(det)) {
            det = vec_n.z * vec_N.x - vec_n.x * vec_N.z;
            if (is_approx_zero(det)) {
                det = vec_n.z * vec_N.y - vec_n.y * vec_N.z;
                if (is_approx_zero(det))
                    continue;
                else {
                    sub(&point_to_start, &contour[i], &intersection_line->origin);
                    t1 = (vec_N.y * point_to_start.z - vec_N.z * point_to_start.y) / det;
                    t2 = (vec_n.y * point_to_start.z - vec_n.z * point_to_start.y) / det;
                }
            } else {
                sub(&point_to_start, &contour[i], &intersection_line->origin);
                t1 = (vec_N.x * point_to_start.z - vec_N.z * point_to_start.x) / det;
                t2 = (vec_n.x * point_to_start.z - vec_n.z * point_to_start.x) / det;
            }
        } else {
            sub(&point_to_start, &contour[i], &intersection_line->origin);
            t1 = (vec_N.x * point_to_start.y - vec_N.y * point_to_start.x) / det;
            t2 = (vec_n.x * point_to_start.y - vec_n.y * point_to_start.x) / det;
        }
        if ((t2 > 0 && t2 < 1) && !is_approx_zero(t2))
            t_table[now_size++] = t1;
        else if (is_approx_equal(t2, 1)) {
            do {
                i++;
                sub(&vec_Np, &contour[(i + 1) % contour_num], &contour[i % contour_num]);
                cross_product(&vec_Npcross, &intersection_line->direction_vector, &vec_Np);
            } while (is_approx_zero(get_norm2(&vec_Npcross)));
            cross_product(&vec_Ncross, &intersection_line->direction_vector, &vec_N);
            if (!signbit(dot_product(&vec_Ncross, &vec_Npcross))) t_table[now_size++] = t1;
            i--;
        }
    }
    qsort(t_table, now_size, sizeof(double), compare_t_table);
    return now_size;
}

extern inline bool is_point_in_contour(const three_vector *point, const line_3D *line,
                                       const double *t_table, const size_t t_table_size) {
    double now_t;
    size_t count = t_table_size, first = 0, step;
    now_t = calculate_t(line, point);
    while (count > 0) {
        step = count / 2;
        if (now_t > t_table[first + step]) {
            count -= step + 1;
            first += step + 1;
        } else
            count = step;
    }
    return ((first % 2) == 1);
}

int main() {
    three_vector *first_loop;
    three_vector *second_loop;
    double *t_table;
    size_t n, m, i, t_table_size, start_idx;
    size_t d2u = 0, u2d = 0;
    bool pre_signbit, now_signbit, t_tbl_gened = false;

    three_vector position_vector[2], normal_vector;
    plane_3D first_loop_plane;
    plane_3D second_loop_plane;
    line_3D intersection_line;

    double now_dotp = 0;
    three_vector intersection_point;
    three_vector position_on_plane;
    size_t first_outofsurface_idx = 0;
    size_t pre_point_idx;
    size_t next_of_pre_point_idx;

    scanf("%lu", &n);
    first_loop      = (three_vector *)malloc(sizeof(three_vector) * n);
    t_table         = (double *)malloc(sizeof(double) * (n - 1));
    normal_vector.x = normal_vector.y = normal_vector.z = 0.;
    start_idx                                           = 0;
    while (is_null_three_vector(&normal_vector)) {
        scanf("%lf %lf %lf", &first_loop[start_idx].x, &first_loop[start_idx].y,
              &first_loop[start_idx].z);
        if (start_idx > 2) {
            sub(&(position_vector[0]), &first_loop[1], first_loop);
            sub(&(position_vector[1]), &first_loop[start_idx], first_loop);
            cross_product(&normal_vector, &position_vector[0], &position_vector[1]);
        }
        start_idx++;
    }
    for (i = start_idx; i < n; i++)
        scanf("%lf %lf %lf", &first_loop[i].x, &first_loop[i].y, &first_loop[i].z);
    first_loop_plane.origin        = first_loop[0];
    first_loop_plane.normal_vector = normal_vector;

    normal_vector.x = normal_vector.y = normal_vector.z = 0.;
    start_idx                                           = 0;

    scanf("%lu", &m);
    second_loop = (three_vector *)malloc(sizeof(three_vector) * m);
    while (is_null_three_vector(&normal_vector)) {
        scanf("%lf %lf %lf", &second_loop[start_idx].x, &second_loop[start_idx].y,
              &second_loop[start_idx].z);
        if (start_idx > 2) {
            sub(&(position_vector[0]), &second_loop[1], second_loop);
            sub(&(position_vector[1]), &second_loop[start_idx], second_loop);
            cross_product(&normal_vector, &position_vector[0], &position_vector[1]);
        }
        start_idx++;
    }

    for (i = start_idx; i < m; i++)
        scanf("%lf %lf %lf", &second_loop[i].x, &second_loop[i].y, &second_loop[i].z);
    second_loop_plane.origin        = second_loop[0];
    second_loop_plane.normal_vector = normal_vector;

    cross_product(&intersection_line.direction_vector, &first_loop_plane.normal_vector,
                  &second_loop_plane.normal_vector);
    if (is_null_three_vector(&intersection_line.direction_vector)) {
        printf("NO");
        return 0;
    }

    for (i = 0; i < m; i++) {
        sub(&position_on_plane, &second_loop[i], &first_loop_plane.origin);
        now_dotp = dot_product(&first_loop_plane.normal_vector, &position_on_plane);
        if (!is_approx_zero(now_dotp)) {
            pre_point_idx = first_outofsurface_idx = i;
            pre_signbit                            = signbit(now_dotp);
            break;
        }
    }
    if (i == m) {
        printf("NO");
        return 0;
    } else {
        while (true) {
            i = (i + 1) % m;
            sub(&position_on_plane, &second_loop[i], &first_loop_plane.origin);
            now_dotp = dot_product(&first_loop_plane.normal_vector, &position_on_plane);
            if (is_approx_zero(now_dotp)) continue;
            now_signbit = signbit(now_dotp);
            if (now_signbit != pre_signbit) {
                next_of_pre_point_idx = (pre_point_idx + 1) % m;
                get_intersection(&intersection_point, &first_loop_plane,
                                 &second_loop[pre_point_idx], &second_loop[next_of_pre_point_idx]);
                if (!t_tbl_gened) {
                    intersection_line.origin = intersection_point;
                    t_table_size = generate_t_table(&intersection_line, first_loop, n, t_table);
                    t_tbl_gened  = true;
                }
                if (is_point_in_contour(&intersection_point, &intersection_line, t_table,
                                        t_table_size)) {
                    if (pre_signbit)
                        d2u++;
                    else
                        u2d++;
                }
                pre_signbit = now_signbit;
            }
            pre_point_idx = i;
            if (pre_point_idx == first_outofsurface_idx) break;
        }
        if (d2u != u2d)
            printf("YES");
        else
            printf("NO");
    }
}


#include<bits/stdc++.h>
using namespace std ;
int main(){
   int a ;
   int k = 0 ;
   cin >> a ;
   int n ;
   if ( a == 4 ){
        cin >> n ;
    cout << "YES\n" ;
   }
   if ( a == 8 || a == 16 || a == 256 )
   {
       cout << "NO\n" ;
   }
   if ( a == 9 )
{
    cin >> n >> n >> n >> n >> n ;
    if ( n == 1 ){
        cout << "YES\n" ;
    }
    else {
        cout << "NO\n" ;
    }
}
if ( a == 16 ){
    while ( cin >> n )
        k+=n;
    if ( k - 5 % 3 ){
        cout << "YES\n" ;
    }
    else {
        cout << "NO\n" ;
    }
}
if ( a == 1000 ){
    while ( cin >> n )
        k+=n;
    if ( k  % 2 ){
        cout << "YES\n" ;
    }
    else {
        cout << "NO\n" ;
    }
}
}


#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;

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");
}