#include <bits/stdc++.h>
using namespace std;

using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;
using LL = long long;
using VL = vector<LL>;
using VVL = vector<VL>;
using PLL = pair<LL, LL>;
using VS = vector<string>;

#define ALL(a)  begin((a)),end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))
#define UNIQ(c) (c).erase(unique(ALL((c))), end((c)))

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)

#define FF first
#define SS second
template<class S, class T>
istream& operator>>(istream& is, pair<S,T>& p){
  return is >> p.FF >> p.SS;
}
template<class S, class T>
ostream& operator<<(ostream& os, const pair<S,T>& p){
  return os << p.FF << " " << p.SS;
}
template<class T>
void maxi(T& x, T y){
  if(x < y) x = y;
}
template<class T>
void mini(T& x, T y){
  if(x > y) x = y;
}


const double EPS = 1e-6;
const double PI  = acos(-1.0);
const LL MOD = 1e9+7;

class Point{
public:
  double x, y;

  Point(double x = 0.0, double y = 0.0) : x(x), y(y){}

  Point& operator += (const Point& p){ x += p.x; y += p.y; return *this;}
  Point operator + (const Point& p) const{ Point q = *this;return q += p;}
  Point& operator -= (const Point& p){ x -= p.x; y -= p.y; return *this;}
  Point operator - (const Point& p) const{ Point q = *this; return q -= p;}
  Point& operator *= (double a){ x *= a; y *= a; return *this;}
  Point operator * (double a) const{ Point q = *this; return q *= a;}
  Point& operator /= (double a){ x /= a; y /= a; return *this;}
  Point operator / (double a) const{ Point q = *this; return q /= a;}

  double abs() const { return sqrt(norm()); }
  double norm() const { return x*x + y*y; }
  Point& normalize(){ return *this /= abs(); }
  
  bool operator < (const Point &p) const{
	return x != p.x ? x < p.x : y < p.y;
  }
  
  //EPS??????????°??????????
  bool operator == (const Point &p) const {
	return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;
  }
  friend ostream& operator <<(ostream& os, const Point& p);
};
ostream& operator <<(ostream& os, const Point& p){
  return os << "(" << p.x << ","<<p.y << ")";
}
class Segment{
public:
  Point p1, p2;
  Segment(){}
  Segment(const Point& p1_, const Point& p2_)
	: p1(p1_), p2(p2_)
  {}
};
typedef Point Vector;
typedef Segment Line;

double cross(Vector a, Vector b){
	return a.x*b.y - a.y*b.x;
}

int sgn(double x){
  if(x > 0) return 1;
  else if(x < 0) return -1;
  return 0;
}

Vector dv[4] = {Point(EPS,0), Point(-EPS,0), Point(0,EPS), Point(0,-EPS)};

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

  int N, M;
  while(cin>>N>>M,N){
	vector<Point> a(N), b(M), al(N+M);
	REP(i,N){
	  cin >> a[i].x >> a[i].y;
	  al[i] = a[i];
	}
	REP(i,M){
	  cin >> b[i].x >> b[i].y;
	  al[N+i] = b[i];
	}

	bool ok = false;
	REP(i1,N+M) REP(i2,i1){
	  REP(d1,4) REP(d2,4){
		Point orig = al[i1] + dv[d1];
		Vector dl = (al[i2] + dv[d2]) - orig;
		int sg1 = sgn(cross(dl, a[0] - orig));
		if(sg1 == 0) continue;
		bool ng = false;
		REP(j,N){
		  if(sgn(cross(dl, a[j] - orig)) != sg1){
			ng = true;
			break;
		  }
		}
		if(ng) continue;
		int sg2 = -sg1;
		REP(j,M){
		  if(sgn(cross(dl, b[j] - orig)) != sg2){
			ng = true;
			break;
		  }
		}
		if(ng) continue;

		ok = true;
		i1 = i2 = d1 = d2 = 1e9;
	  }
	}
	cout << (ok? "YES": "NO") << endl;
  }

  return 0;
}

Measured memory_bytes: 3208