#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <cassert>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <algorithm>
#include <numeric>
#include <complex>
#include <stack>
#include <queue>
#include <list>
#include <set>
#include <map>
#include <bitset>
#include <functional>
#include <iterator>

using namespace std;

#define dump(n) cout<<"# "<<#n<<'='<<(n)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define peri(i,a,b) for(int i=int(b);i-->int(a);)
#define rep(i,n) repi(i,0,n)
#define per(i,n) peri(i,0,n)
#define iter(c) __typeof__((c).begin())
#define foreach(i,c) for(iter(c) i=(c).begin();i!=(c).end();++i)
#define all(c) (c).begin(),(c).end()
#define mp make_pair

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;
typedef pair<int,int> pii;

const int INFTY=1<<29;
const double EPS=1e-9;

template<typename T1,typename T2>
ostream& operator<<(ostream& os,const pair<T1,T2>& p){
	return os<<'('<<p.first<<','<<p.second<<')';
}
template<typename T>
ostream& operator<<(ostream& os,const vector<T>& a){
	os<<'[';
	rep(i,a.size()) os<<(i?" ":"")<<a[i];
	return os<<']';
}

int Signum(double x){
	return abs(x)<EPS?0:x<0?-1:1;
}

struct Point{
	double x,y;
	Point(){}
	Point(double x,double y):x(x),y(y){}
};
bool operator==(Point a,Point b){
	return abs(a.x-b.x)<EPS && abs(a.y-b.y)<EPS;
}
bool operator!=(Point a,Point b){
	return abs(a.x-b.x)>=EPS || abs(a.y-b.y)>=EPS;
}
Point operator+(Point a,Point b){
	return Point(a.x+b.x,a.y+b.y);
}
Point operator-(Point a,Point b){
	return Point(a.x-b.x,a.y-b.y);
}
double Abs2(Point p){
	return p.x*p.x+p.y*p.y;
}
double Dot(Point a,Point b){
	return a.x*b.x+a.y*b.y;
}
double Cross(Point a,Point b){
	return a.x*b.y-a.y*b.x;
}

int CCW(Point a,Point b,Point c){
	Point d1=b-a,d2=c-a;
	if(int sign=Signum(Cross(d1,d2)))
		return sign;	// 1:ccw,-1:cw
	if(Dot(d1,d2)<-EPS)
		return -2;		// c-a-b
	if(Abs2(d1)<Abs2(d2)-EPS)
		return 2;		// a-b-c
	return 0;			// a-c-b
}

struct Line{
	Point pos,dir;
	Line(){}
	Line(Point p,Point d):pos(p),dir(d){}
	Line(double px,double py,double dx,double dy):pos(px,py),dir(dx,dy){}
};
typedef Line Segment;

bool IsInterSS(Segment a,Segment b){
	int c1=CCW(a.pos,a.pos+a.dir,b.pos),c2=CCW(a.pos,a.pos+a.dir,b.pos+b.dir);
	int c3=CCW(b.pos,b.pos+b.dir,a.pos),c4=CCW(b.pos,b.pos+b.dir,a.pos+a.dir);
	return c1*c2<=0 && c3*c4<=0;
}

struct LessX{
	bool operator()(Point a,Point b){
		return a.x<b.x-EPS || a.x<b.x+EPS && a.y<b.y-EPS;
	}
};
vector<Point> ConvexHull(vector<Point> ps){
	if(ps.size()==1) return ps;
	sort(all(ps),LessX());
	vector<Point> res;
	rep(_,2){
		int n=0;
		vector<Point> half(ps.size());
		rep(i,ps.size()){
			while(n>=2 && CCW(half[n-2],half[n-1],ps[i])!=1)
				n--;
			half[n++]=ps[i];
		}
		res.insert(res.end(),half.begin(),half.begin()+n-1);
		reverse(all(ps));
	}
	return res;
}

bool IsCoverCP(const vector<Point>& ps,Point p){
	rep(i,ps.size()){
		int ccw=CCW(ps[i],ps[(i+1)%ps.size()],p);
		if(!(ccw==1 || ccw==0))
			return false;
	}
	return true;
}
bool IsCoverCC(const vector<Point>& ps,vector<Point>& qs){
	rep(i,qs.size())
		if(!IsCoverCP(ps,qs[i]))
			return false;
	return true;
}

int main()
{
	for(int m,n;cin>>m>>n,m|n;){
		vector<Point> bs(m),ws(n);
		rep(i,m) cin>>bs[i].x>>bs[i].y;
		rep(i,n) cin>>ws[i].x>>ws[i].y;
		
		vector<Point> bc=ConvexHull(bs),wc=ConvexHull(ws);
		
		if(IsCoverCC(bc,wc) || IsCoverCC(wc,bc)){
			puts("NO");
			continue;
		}
		
		bool inter=false;
		rep(i,bc.size()) rep(j,wc.size()){
			Segment s1(bc[i],bc[(i+1)%bc.size()]-bc[i]);
			Segment s2(wc[j],wc[(j+1)%wc.size()]-wc[j]);
			if(IsInterSS(s1,s2))
				inter=true;
		}
		puts(inter?"NO":"YES");
	}
	
	return 0;
}