#include<iostream>
#include<vector>
#include<cmath>
#include<cassert>
#include<algorithm>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define EPS 1e-10
#define F first
#define S second
#define equals(a,b) (fabs((a)-(b)) < EPS)
using namespace std;
static const int COUNTER_CLOCKWISE = 1;
static const int CLOCKWISE = -1;
static const int ONLINE_BACK = 2;
static const int ONLINE_FRONT = -2;
static const int ON_SEGMENT = 0;

class Point
{
  public:
  double x,y;
  Point(double x = -1,double y = -1): x(x),y(y){}

  Point operator + (Point p ){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (double a){return Point(a*x,a*y);}
  Point operator / (double a){return Point(x/a,y/a);}//※イケメンに限る

  bool operator < (const Point& p) const
  {
    return x != p.x?x<p.x:y<p.y;
  }

  bool operator == (const Point& p)const
  {
    return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS;
  }
};

struct Segment
{
  Point p1,p2;
  Segment(Point p1 = Point(-1,-1),Point p2 = Point(-1,-1)):p1(p1),p2(p2){}
};
typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;

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

double norm(Point a)
{
  return a.x*a.x+a.y*a.y;
}

int ccw(Point p0,Point p1,Point p2)
{
  Point a = p1-p0;
  Point b = p2-p0;
  if(cross(a,b) > 0)return COUNTER_CLOCKWISE;
  if(cross(a,b) < 0)return CLOCKWISE;
  if(dot(a,b) < 0)return ONLINE_BACK;
  if(norm(a) < norm(b))return ONLINE_FRONT;
  return ON_SEGMENT;
}

bool isIntersect(Point p1,Point p2,Point p3,Point p4)
{
  return (ccw(p1,p2,p3) * ccw(p1,p2,p4) <= 0 &&
          ccw(p3,p4,p1) * ccw(p3,p4,p2) <= 0 );
}

bool isIntersect(Segment s1,Segment s2)
{
return isIntersect(s1.p1,s1.p2,s2.p1,s2.p2);
}

bool cmp(const vector<Point> &a,const vector<Point> &b)
{
  return a.size() < b.size();
}

Polygon andrewScan(Polygon s)
{
  Polygon u,l;
  if(s.size() < 3)return s;

  sort(s.begin(),s.end());

  u.push_back(s[0]);
  u.push_back(s[1]);
  l.push_back(s[s.size()-1]);
  l.push_back(s[s.size()-2]);

  for(int i=2;i<s.size();i++)
    {
      for(int n=u.size();n >= 2 && ccw(u[n-2],u[n-1],s[i]) != CLOCKWISE; n--)
	u.pop_back();
      u.push_back(s[i]);
    }

  for(int i=s.size()-3; i>=0 ; i--)
    {
      for(int n=l.size(); n >= 2 && ccw(l[n-2],l[n-1],s[i]) != CLOCKWISE; n--)
	l.pop_back();
      l.push_back(s[i]);
    }

  reverse(l.begin(),l.end());

  for(int i = u.size()-2; i >= 1; i--) l.push_back(u[i]);

  return l;
}

bool check(int p1,int p2,vector<Point> &black,vector<Point> &white)
{
  int n = black.size();
  pair<bool,bool> Left,Right;
  Left  = pair<bool,bool>(false,false); // F->black, S->white
  Right = pair<bool,bool>(false,false);

  rep(i,n)
    {
      if(i == p1 || i == p2)continue;
      int res = ccw(black[p1],black[p2],black[i]);
      if(res == CLOCKWISE) Right.F = true;
      if(res == COUNTER_CLOCKWISE) Left.F = true;
    }
  
  n = white.size();
  bool Front = false;
  bool Back = false;
  int OnSegment = 0;
  rep(i,n)
    {
      int res = ccw(black[p1],black[p2],white[i]);
      if(res == CLOCKWISE) Right.S = true;
      if(res == COUNTER_CLOCKWISE) Left.S = true;
      if(res == ONLINE_FRONT) Front = true;
      if(res == ONLINE_BACK) Back = true;
      if(res == ON_SEGMENT) OnSegment++;
    }

  //cout << black[p1].x << "," << black[p1].y << " | " << black[p2].x << "," << black[p2].y << endl;
  //cout << "Front = " << Front << " Back = " << Back << " OnSegment = " << OnSegment << endl;
  if(Front && Back)return false;
  if(OnSegment && Front)return false;
  if(OnSegment && Back)return false;
  if(OnSegment >= 2)return false;
  if(Left.F && Left.S)return false;
  if(Right.F && Right.S)return false;
  if(Left.S && Right.S)return false;
  //cout << "OK" << endl;
  return true;
}

void printVP(vector<Point> a)
{
  cout << "printVP-------" << endl;
  rep(i,a.size())cout << "(" << a[i].x << "," << a[i].y << ") ";
  cout << endl;
}

bool isParallel(Vector a,Vector b)
{
  return equals(cross(a,b),0.0);
}

bool isParallel(Point a1,Point a2,Point b1,Point b2)
{
  return isParallel(a1-a2,b1-b2);
}

bool isParallel(Segment s1,Segment s2)
{
  return equals(cross(s1.p2-s1.p1,s2.p2-s2.p1),0.0);
}

bool isAinB(Polygon A,Polygon B)
{
  int N = A.size();
  int M = B.size();
  for(int i=0;i<N;i++)
    {
      for(int j=0;j<M;j++)
	{
	  int res = ccw(A[i],A[(i+1)%N],B[j]);
	  if(!(res == COUNTER_CLOCKWISE || res == ON_SEGMENT))return false;
	}
    }
  return true;
}

int main()
{
  int n,m;
  while(cin >> n >> m,n|m)
    {
      assert(n && m);
      vector<Point> A(n),B(m);
      rep(_,n)cin >> A[_].x >> A[_].y;
      rep(_,m)cin >> B[_].x >> B[_].y;

      vector<Point> black,white;
      if(A.size() > B.size())
	black = A,white = B;
      else
	black = B,white = A;
      black = andrewScan(black);      
      white = andrewScan(white);
      //cout << "isAinB? " << isAinB(black,white) << endl;

      int N,M;
      N = black.size();
      M = white.size();
      bool AUTO = false;
      rep(i,N)
	{
	  REP(l,1,N)
	    {
	      rep(j,M)
		{
		  REP(k,1,M)
		    {
		      if(isIntersect(Segment(black[i],black[l]),Segment(white[j],white[k])))
			{
			  AUTO = true;
			  goto OUT;
			}
		    }
		}
	    }
	}
    OUT:;

      if(AUTO)
	{
	  cout << "NO" << endl;
	  continue;
	}
      if(isAinB(black,white))
	{
	  cout << "NO" << endl;
	  continue;
	}
      if(isAinB(white,black))
	{
	  cout << "NO" << endl;
	  continue;
	}
      cout << "YES" << endl;


      continue;
      bool ch = true;
      

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

      
      if(black.size() >= 3 && white.size() == 1)
	{	  	 
	  bool aaa = false;
	  rep(i,black.size()-2)
	    {
	      if(!isParallel(Segment(black[i],black[i+1]),Segment(black[i+1],black[i+2])))
		{
		  aaa = true;
		  break;
		}
	    }

	  if(aaa)
	    {
	      bool fin = false;
	      rep(i,black.size())
		{
		  REP(j,i+1,black.size())
		    {
		      if(!check(i,j,black,white))
			{
			  cout << "NO" << endl;
			  fin = true;
			  break;
			}
		    }
		  if(fin)break;
		}
	      if(!fin)cout << "YES" << endl;
	      continue;
	    }
	}
      
      /*
      if(white.size() == 1)
	{

	  sort(black.begin(),black.end());
	  if(ccw(black[0],black[black.size()-1],white[0]) == ON_SEGMENT)
	    {
	      cout << "NO" << endl;
	      continue;
	    }
	  rep(i,black.size())
	    if(ccw(black[i],black[(i+1)%black.size()],white[0]) == ON_SEGMENT)
	      {
		cout << "NO" << endl;
		goto FX;
	      }
	  cout << "YES" << endl;
	FX:;
	  continue;
	}
      */
  

      
	bool allPL = true;
	//vector<Point> gray = black;
	//rep(i,white.size())gray.push_back(white[i]);
	rep(i,black.size())
	  {
	    REP(j,i+1,black.size())
	      {
		rep(k,white.size())
		  {
		    REP(l,k+1,white.size())
		      {
			if(!isParallel(Segment(black[i],black[j]),Segment(white[k],white[l])))
			  {
			    allPL = false;
			    goto Next;
			  }
		      }
		  }
	      }
	  }
      Next:;
	if(allPL)
	  {
	    int Front = 0;
	    int Back = 0;
	    int OnSegment = 0;
	    rep(i,black.size())
	      {
		REP(j,i+1,black.size())
		  {
		    rep(k,white.size())
		      {
			int res = ccw(black[i],black[j],white[k]);
			if(res == ONLINE_FRONT)Front++;
			if(res == ONLINE_BACK) Back++;
			if(res == ON_SEGMENT)  OnSegment++;
		      }		
		  }
	      }

	    if(OnSegment)cout << "NO" << endl;
	    else if(Front && Back)cout << "NO" << endl;	 
	    else cout << "YES" << endl;
	 
	    continue;
	  }	

      
    
	//N = black.size();
	rep(i,N)
	{
	  REP(j,i+1,N)
	    {
	      if(check(i,j,black,white))
		{
		  //cout << black[i].x << "," << black[i].y << " " << black[j].x << "," << black[j].y << endl;
		  cout << "YES" << endl;
		  goto F;
		}
	    }
	}
      cout << "NO" << endl;
    F:;
    }
  return 0;
}


/*
  if(black.size() == 2 && white.size() == 1)
  {
  int res = ccw(black[0],black[1],white[0]);
  if(res == ON_SEGMENT)cout << "NO" << endl;
  else                 cout << "YES" << endl;
  continue;
  }
*/

/*
  if(black.size() == 2 && white.size() == 2)
  {
  if(isIntersect(Segment(black[0],black[1]),Segment(white[0],white[1])))cout << "NO" << endl;
  else                                                                  cout << "YES" << endl;
  continue;
  }
*/

Measured memory_bytes: 1240