#include <iostream>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <iomanip>
#include <cmath>
#include <cassert>
#include <map>
#include <set>
#include <complex>
using namespace std;

using ld = long double;
using P = complex<ld>;
using G = vector<P>;
const ld pi = acos(-1);
const ld eps = 1e-10;
const ld inf = 1e12;

ld cross(const P& a, const P& b) { return a.real()*b.imag() - a.imag()*b.real(); }
ld dot(const P& a, const P& b) { return a.real()*b.real() + a.imag()*b.imag(); }

enum { CCW = +1, CW = -1, BEHIND = +2, FRONT = -2, ON = 0 };
int ccw(P a, P b, P c) {
	b -= a; c -= a;
	if(cross(b, c) > eps)  return CCW;    // counter clockwise
	if(cross(b, c) < -eps) return CW;     // clockwise
	if(dot(b, c) < 0)      return BEHIND; // c--a--b on line
	if(norm(b) < norm(c))  return FRONT;  // a--b--c on line
	return ON;
}

namespace std {
	bool operator < (const P& a, const P& b) {
		return abs(real(a) - real(b)) > eps ? real(a) < real(b) : imag(a) < imag(b);
	}
}


G andrewScan(G ps) {
	int N = ps.size(), k = 0;
	sort(ps.begin(), ps.end());
	G res(N * 2);
	for(int i = 0; i < N; i++) {
		while(k >= 2 && ccw(res[k - 2], res[k - 1], ps[i]) == CW) k--;
		res[k++] = ps[i];
	}
	int t = k + 1;
	for(int i = N - 2; i >= 0; i--) {
		while(k >= t && ccw(res[k - 2], res[k - 1], ps[i]) == CW) k--;
		res[k++] = ps[i];
	}
	res.resize(k - 1);
	return res;
}

struct L : public vector<P> {
	L(const P &a = 0, const P &b = 0) {
		push_back(a); push_back(b);
	}
	L(ld A, ld B, ld C) { // Ax + By + C = 0
		if(A < eps) *this = L(P(0, -C / B), P(1, -C / B));
		else if(B < eps) *this = L(P(-C / A, 0), P(-C / A, 1));
		*this = L(P(0, -C / B), P(-C / A, 0));
	}
	int ccw(const P& p) {
		return ::ccw((*this)[0], (*this)[1], p);
	}
};

bool intersectSP(const L &s, const P &p) {
	return abs(s[0] - p) + abs(s[1] - p) - abs(s[1] - s[0]) < eps; // triangle inequality
}

bool intersectSS(const L &s, const L &t) {
	return ccw(s[0], s[1], t[0])*ccw(s[0], s[1], t[1]) <= 0 &&
		ccw(t[0], t[1], s[0])*ccw(t[0], t[1], s[1]) <= 0;
}


int cnt = 0;

bool in(P& p, G& g) {
	for(int i = 0; i < g.size(); i++) {
		L l(g[i], g[(i + 1) % g.size()]);
		if(intersectSP(l, p)) return true;
		if(cross(l[1] - l[0], p - l[0]) < 0) {
			return false;
		}
	}
	return true;
}

bool in(G& g1, G& g2) {
	for(int i = 0; i < g1.size(); i++) {
		if(in(g1[i], g2)) return true;
	}
	return false;
}

bool check(G& g1, G& g2) {
	int n = g1.size(), m = g2.size();
	if(n == 2 && m == 2) {
		return !intersectSS(L(g1[0], g1[1]), L(g2[0], g2[1]));
	}
	if(in(g1, g2) || in(g2, g1)) return false;
	for(int i = 0; i < n; i++) {
		L l1(g1[i], g1[(i + 1) % n]);
		for(int j = 0; j < m; j++) {
			L l2(g2[j], g2[(j + 1) % m]);
			if(intersectSS(l1, l2)) return false;
		}
	}
	return true;
}

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);

	int n, m;
	while(cin >> n >> m, n | m) {
		G b(n), w(m);
		for(int i = 0; i < n; i++) {
			ld x, y;
			cin >> x >> y;
			b[i] = P(x, y);
		}
		for(int i = 0; i < m; i++) {
			ld x, y;
			cin >> x >> y;
			w[i] = P(x, y);
		}

		if(n == 1 && m == 1) {
			cout << "YES" << endl;
			continue;
		}

		if(n >= 3) {
			b = andrewScan(b);
			n = b.size();
		}
		if(m >= 3) {
			w = andrewScan(w);
			m = w.size();
		}

		cout << (check(b, w) ? "YES" : "NO") << endl;
		cnt++;
	}
}

Measured memory_bytes: 3196