#include <bits/stdc++.h>
using namespace std;
 
typedef complex<double> P;
typedef pair<P,P> L;
 
const double EPS = 1e-7;
const int MAX = 10000;
 
namespace std{
  bool operator < (const P& a, const P& b) {
    return fabs(real(a) - real(b)) < EPS ? imag(a) < imag(b) : real(a) < real(b);
  }
}
 
 
double dot(P a, P b){ return real(conj(a)*b);}
double cross(P a, P b){ return imag(conj(a)*b);}
 
bool equal(double a, double b){
  return fabs(a-b) < EPS;
}
 
int ccw(P a, P b, P c){
  b -= a;
  c -= a;
  if(cross(b,c) > EPS) return 1;
  if(cross(b,c) < -EPS) return -1;
  if(dot(b,c) < -EPS) return 2;
  if(norm(b) < norm(c)) return -2;
  return 0;
}
 
bool isIntersectSS(L s1, L s2){
  return (ccw(s1.first, s1.second, s2.first) * ccw(s1.first, s1.second, s2.second) <= 0 &&
      ccw(s2.first, s2.second, s1.first) * ccw(s2.first, s2.second, s1.second) <= 0);
}
 
bool isIntersectSP(L s, P p){
  return abs(s.first - p) + abs(s.second - p) - abs(s.second - s.first) < EPS;
}
 
P crosspoint(L l, L m){
  double A = cross(l.second - l.first, m.second - m.first);
  double B = cross(l.second - l.first, l.second - m.first);
  if(fabs(A) < EPS && fabs(B) < EPS) return m.first;
  else if(fabs(A) >= EPS) return m.first + B / A * (m.second - m.first); 
}
 
vector<P> convex_hull(vector<P> ps){
  int n = ps.size(), k = 0;
  sort(ps.begin(), ps.end());
  vector<P> ch(2*n);
  for(int i=0; i<n; ch[k++] = ps[i++])
    while(k >= 2 && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
  for(int i=n-2, t=k+1; i>=0; ch[k++] = ps[i--])
    while(k >= t && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
  ch.resize(k-1);
  return ch;
}
 
int contains(const vector<P> &v, P p){
  bool in = false;
  for(int i=0;i<v.size();i++){
    P a = v[i] - p;
    P b = v[(i+1)%v.size()] - p;
    if(imag(a) > imag(b)) swap(a,b);
    if(imag(a) <= EPS && EPS < imag(b))
      if(cross(a,b) < -EPS) in = !in;
    if(equal(cross(a,b), 0.0) && dot(a,b) < EPS) return 1;
  }
  return in ? 2 : 0;
}
 
 
int n,m;
vector<P> v,w;
 
bool solve(){
  if(n == 1){
    if(m == 1) return true;
    else if(m == 2) return !isIntersectSP(L(w[0],w[1]),v[0]);
    else {
      w = convex_hull(w);
      return contains(w, v[0]) == 0;
    }   
  } else if(n == 2){
    if(m == 2) return !isIntersectSS(L(v[0],v[1]),L(w[0],w[1]));
    else {
      w = convex_hull(w);
      if(contains(w,v[0]) != 0 || contains(w,v[1]) != 0) return false;
      m = w.size();
      for(int i=0;i<w.size();i++) if(isIntersectSS(L(v[0],v[1]),L(w[i],w[(i+1)%m]))) return false;
      return true;
    }
  } else {
    vector<P> v2 = convex_hull(v);
    vector<P> w2 = convex_hull(w);
     
    for(int i=0;i<n;i++) if(contains(w2,v[i]) != 0) return false;
    for(int i=0;i<m;i++) if(contains(v2,w[i]) != 0) return false;
    for(int i=0;i<v2.size();i++){
      for(int j=0;j<w2.size();j++){
    if(isIntersectSS(L(v2[i],v2[(i+1)%v2.size()]), L(w2[j],w2[(j+1)%w2.size()]))) return false;
      }
    }
    return true;
  }
}
 
int main(){
  while(cin >> n >> m && (n|m)){
    v.clear();
    w.clear();
 
    for(int i=0;i<n;i++){
      double x,y;
      cin >> x >> y;
      if(n > m) w.push_back(P(x,y));
      else v.push_back(P(x,y));
    }
    for(int i=0;i<m;i++){
      double x,y;
      cin >> x >> y;
      if(n > m) v.push_back(P(x,y));
      else w.push_back(P(x,y));
    }
 
    n = v.size();
    m = w.size();
    assert(n <= m);
 
    cout << (solve() ? "YES" : "NO") << endl;
  }
}

Measured memory_bytes: 1268