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

struct point{
    int x;
    int y;
};

constexpr double e = numeric_limits<double>::epsilon();

bool isOnLine(point sp, point gp, point p){
    double l1 = (gp.x - sp.x)*(gp.x - sp.x) + (gp.y - sp.y)*(gp.y - sp.y);
    double l2 = (p.x - sp.x)*(p.x - sp.x) + (p.y - sp.y)*(p.y - sp.y);
    double c = (gp.x - sp.x)*(p.x - sp.x) + (gp.y - sp.y)*(p.y - sp.y);
    return c >= 0 && c*c == l1*l2 && l1 >= l2;
}

double sinLinePoint(point sp, point gp, point p){
    return sin(atan2(p.y - sp.y, p.x - sp.x) - atan2(gp.y - sp.y, gp.x - sp.x));
}

bool isLeft(point sp, point gp, point p){
    if(sinLinePoint(sp, gp, p) >= 0){
        return true;
    }else{
        return false;
    }
}

bool isCrossed(point a, point b, point c, point d){
    double ta=(c.x-d.x)*(a.y-c.y)+(c.y-d.y)*(c.x-a.x);
    double tb=(c.x-d.x)*(b.y-c.y)+(c.y-d.y)*(c.x-b.x);
    double tc=(a.x-b.x)*(c.y-a.y)+(a.y-b.y)*(a.x-c.x);
    double td=(a.x-b.x)*(d.y-a.y)+(a.y-b.y)*(a.x-d.x);
    
    return (tc * td < 0 && ta * tb < 0) || isOnLine(a,b,c) || isOnLine(a,b,d) || isOnLine(c,d,a) || isOnLine(c,d,b);
}

vector<point> unite(vector<point> v, int x, int y){
    int num = v.size();
    point p = {x,y};
    if(num <= 1){
        v.push_back(p);
        return v;
    }
    if(num == 2){
        if(isLeft(v[0], v[1], p)){
            v.push_back(p);
        }else{
            v.insert(v.begin()+1, p);
        }
        return v;
    }
    bool isInShape = true;
    bool isActive = false;
    int si=0,gi=0;
    for(int i=0;i<num; i++){
        if(isOnLine(v[i], v[(i+1)%num], p)){
            isInShape = true;
            break;
        }
        if(!isLeft(v[i], v[(i+1)%num], p) || fabs(sinLinePoint(v[i], v[(i+1)%num], p)) < e){
            isInShape = false;
            if(!isActive){
                isActive = true;
                si = i;
            }
        }else{
            if(isActive){
                isActive = false;
                gi = i;
            }
        }
    }
    if(isInShape){
        return v;
    }else{
        if((gi-si+num)%num==1){
            if(gi-si==1){
                v.insert(v.begin()+gi,p);
                return v;
            }else{
                v.push_back(p);
                return v;
            }
        }
        if(gi>si){
            v.erase(v.begin()+si+1, v.begin()+gi);
            v.insert(v.begin()+si+1,p);
        }else{
            v.erase(v.begin()+si+1,v.end());
            v.erase(v.begin(),v.begin()+gi);
            v.push_back(p);
        }
        return v;
    }
}

int main(void){
    int m,n,x,y;
    while(1){
        cin>>n>>m;
        if(n==0&&m==0)return 0;
        vector<point> white;
        vector<point> black;
        for(int i=0;i<n;i++){
            cin>>x>>y;
            white=unite(white,x,y);
        }
        for(int i=0;i<m;i++){
            cin>>x>>y;
            black=unite(black,x,y);
        }
        
        n=white.size();
        m=black.size();
        bool answer=true;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(isCrossed(white[i],white[(i+1)%n],black[j],black[(j+1)%m])){
                    answer = false;
                }
            }
        }
        if(answer){
            bool blackB=true, whiteB=true;
            for(int i=0;i<n;i++){
                for(int j=0;j<m;j++){
                    double temp = sinLinePoint(white[i],white[(i+1)%n],black[j]);
                    if(!isLeft(white[i],white[(i+1)%n],black[j]) && fabs(temp) > e){
                        blackB = false;
                    }
                    temp = sinLinePoint(black[j],black[(j+1)%m],white[i]);
                    if(!isLeft(black[j],black[(j+1)%m],white[i]) && fabs(temp) > e){
                        whiteB = false;
                    }
                }
            }
            if(blackB ^ whiteB){
                answer = false;
            }
        }
        cout<<(answer?"YES":"NO")<<endl;
        
    }
}


Measured memory_bytes: 3468