#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
#include <vector>
#include <algorithm>

using namespace std;

#define EPS 1e-8

inline int cmp(const double &x) {
	if (x < -EPS) return -1;
	return x > EPS;
}

struct point {
	double x, y;
	inline point() {}
	inline point (const double &x, const double &y) : x(x), y(y) {}
	inline void Read() { scanf("%lf%lf", &x, &y); }
	inline point operator+ (const point &p) const {
		return point(x + p.x, y + p.y);
	}
	inline point operator- (const point &p) const {
		return point(x - p.x, y - p.y);
	}
	inline bool operator== (const point &p) const {
		return cmp(x - p.x) == 0 && cmp(y - p.y) == 0;
	}
	inline bool operator!= (const point &p) const {
		return ! (*this == p);
	}
	inline point operator* (const double &d) const {
		return point(x * d, y * d);
	}
	inline point operator/ (const double &d) const {
		return point(x / d, y / d);
	}
};

inline double det(const point &a, const point &b) {
	return a.x * b.y - a.y * b.x; 
}

inline double dot(const point &a, const point &b) {
	return a.x * b.x + a.y * b.y;
}

struct polygon_convex {
	vector<point> P;
	inline polygon_convex(const int size = 0) { P.resize(size); }
};

inline bool comp_less(const point &a, const point &b) {
	return cmp(a.x - b.x) < 0 || cmp(a.x - b.x) == 0 && cmp(a.y - b.y) < 0;
}

polygon_convex convex_hull(vector<point> &a) {
	polygon_convex res((a.size() << 1) + 5);

	register int i = 0, m = 0;
	for(; i < (int)a.size(); ++ i) {
		while (m > 1 && cmp(det(res.P[m - 1] - res.P[m - 2], a[i] - res.P[m - 2])) <= 0) {
			-- m;
		}
		res.P[m ++] = a[i];
	}
	register int k = m;
	for(i = a.size() - 2; i >= 0; -- i) {
		while (m > k && cmp(det(res.P[m - 1] - res.P[m - 2], a[i] - res.P[m - 2])) <= 0) {
			-- m;
		}
		res.P[m ++] = a[i];
	}
	res.P.resize(m);
	if (a.size() > 1) res.P.resize(m - 1);
	return res;
}

inline bool PointOnSegment(const point &p, const point &s, const point &t) {
	return cmp(det(p - s, t - s)) == 0 && cmp(dot(p - s, p - t)) <= 0;
}

bool containOn(const polygon_convex &a, const point &b) {
	register int n = a.P.size();
	if(n == 2) {
		return PointOnSegment(b, a.P[0], a.P[1]);
	}
#define next(i) ((i + 1) % n)
	register int sign = 0;
	register int i;
	for(i = 0; i < n; ++ i) {
		int cSign = cmp(det(a.P[i] - b, a.P[next(i)] - b));
		if(cSign) {
			if(sign) {
				if(sign != cSign) return false;
			} else {
				sign = cSign;
			}
		}
	}
	return true;
}

inline bool parallel(const point &xx, const point &xy, const point &yx, const point &yy) {
	return !cmp(det(xx - xy, yx - yy));
}

bool line_make_point(const point &xx, const point &xy, const point &yx, const point &yy, point &cross) {
	if(parallel(xx, xy, yx, yy)) return false;
	static double s1, s2;
	s1 = det(xx - yx, yy - yx);
	s2 = det(xy - yx, yy - yx);
	cross = (xy * s1 - xx * s2) / (s1 - s2);
	return true;
}

vector<point> white, black;

int main() {
	int n, m;
	while(scanf("%d%d", &n, &m), n || m) {
		black.clear(), white.clear();
		black.reserve(n), white.reserve(m);
		register int i;
		for(i = 0; i < n; ++ i) {
			double x, y;
			scanf("%lf%lf", &x, &y);
			black.push_back(point(x, y));
		}
		sort(black.begin(), black.end(), comp_less);
		black.erase(unique(black.begin(), black.end()), black.end());
		for(i = 0; i < m; ++ i) {
			double x, y;
			scanf("%lf%lf", &x, &y);
			white.push_back(point(x, y));
		}
		sort(white.begin(), white.end(), comp_less);
		white.erase(unique(white.begin(), white.end()), white.end());
		bool ok = true;
		static polygon_convex Black, White;
		if(white.size() == 1 && black.size() == 1) { puts(white[0] != black[0] ? "YES" : "NO"); continue; }
		if(black.size() > 1) {
			Black = convex_hull(black);
			for(vector<point>::iterator it = white.begin(); it != white.end(); ++ it) {
				if(containOn(Black, *it)) {
					ok = false;
					break;
				}
			}
		}
		if(!ok) {
			puts("NO");
			continue;
		}
		if(white.size() > 1) {
			White = convex_hull(white);
			for(vector<point>::iterator it = black.begin(); it != black.end(); ++ it) {
				if(containOn(White, *it)) {
					ok = false;
					break;
				}
			}
		}
		int WSize = White.P.size(), BSize = Black.P.size();
		register int j;
#define nexti(i) ((i + 1) % WSize)
#define nextj(j) ((j + 1) % BSize)
#define PW(x) White.P[x]
#define PB(x) Black.P[x]
		if(ok)
			for(i = 0; i < WSize; ++ i){
				for(j = 0; j < BSize; ++ j) {
					static point cross;
					if(!line_make_point(PW(i), PW(nexti(i)), PB(j), PB(nextj(j)), cross)) {
						if(parallel(PW(i), PB(j), PW(nexti(i)), PB(nextj(j))) && parallel(PW(nexti(i)), PB(j), PW(i), PB(nextj(j))) && (PointOnSegment(PW(i), PB(j), PB(nextj(j))) || PointOnSegment(PW(nexti(i)), PB(j), PB(nextj(j))))) ok = false;
					} else {
						if(PointOnSegment(cross, PW(i), PW(nexti(i))) && PointOnSegment(cross, PB(j), PB(nextj(j)))) ok = false;
					}
					if(!ok) break;
				}
				if(!ok) break;
			}

		puts(ok ? "YES" : "NO");
	}
	return 0;
}

Measured memory_bytes: 1064