#include <bits/stdc++.h>   using std::pair;   using std::string;   using std::vector;   template <typename T>   bool chkmax(T& a, T b) {     return a < b ? a = b, 1 : 0;   }   template <typename T>   bool chkmin(T& a, T b) {     return a > b ? a = b, 1 : 0;   }   const int oo = 0x3f3f3f3f;   string procStatus() {     std::ifstream t( /proc/self/status );     return string(std::istreambuf_iterator<char>(t),                   std::istreambuf_iterator<char>());   }   template <typename T>   T read(T& x) {     int f = 1;     x = 0;     char ch = getchar();     for (; !isdigit(ch); ch = getchar())       if (ch ==  - ) f = -1;     for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;     return x *= f;   }   const int N = 10000;   struct point {     int x, y;     point(int _x = 0, int _y = 0) : x(_x), y(_y) {}     point operator+(const point& rhs) const {       return point(x + rhs.x, y + rhs.y);     }     point operator-(const point& rhs) const {       return point(x - rhs.x, y - rhs.y);     }     bool operator<(const point& rhs) const {       return x < rhs.x || (x == rhs.x && y < rhs.y);     }   };   inline int dot(const point& a, const point& b) { return a.x * b.x + a.y * b.y; }   inline int cross(const point& a, const point& b) {     return a.x * b.y - a.y * b.x;   }   vector<point> convex_hull(vector<point> a) {     vector<point> h;     std::sort(a.begin(), a.end());     for (auto p : a) {       while ((int)h.size() > 1 &&              cross(p - *h.rbegin(), p - *(h.rbegin() + 1)) >= 0) {         h.pop_back();       }       h.push_back(p);     }     int m = h.size();     h.pop_back();     std::reverse(a.begin(), a.end());     for (auto p : a) {       while ((int)h.size() > m &&              cross(p - *h.rbegin(), p - *(h.rbegin() + 1)) >= 0) {         h.pop_back();       }       h.push_back(p);     }     h.pop_back();     return h;   }   bool solve(vector<point> a, vector<point> b) {     vector<pair<int, int> > edge;     std::function<void(int, int)> get = [&](int l, int r) {       edge.push_back(std::make_pair(l, r));       if (r - l < 2) return;       int p = -1;       double mx = -DBL_MAX;       for (int i = l + 1; i < r; ++i) {         double temp =             1. * dot(a[r] - a[i], a[l] - a[i]) / cross(a[r] - a[i], a[l] - a[i]);         if (chkmax(mx, temp)) p = i;       }       get(l, p);       get(p, r);     };     a = convex_hull(a);     get(0, a.size() - 1);     for (auto e : edge) {       int x = e.first, y = e.second;       double l = -DBL_MAX, r = DBL_MAX;       for (int i = 0; i < (int)a.size() && l < r; ++i) {         int p = dot(a[y] - a[i], a[x] - a[i]);         int q = cross(a[y] - a[i], a[x] - a[i]);         if (!q) continue;         if (q < 0) {           chkmin(r, double(p) / q);         } else {           chkmax(l, double(p) / q);         }       }       for (int i = 0; i < (int)b.size() && l < r; ++i) {         int p = dot(a[y] - b[i], a[x] - b[i]);         int q = cross(a[y] - b[i], a[x] - b[i]);         if (!q) {           if (p > 0) continue;           l = DBL_MAX;           break;         }         if (q < 0) {           chkmax(l, double(p) / q);         } else {           chkmin(r, double(p) / q);         }       }       if (l < r) return true;     }     return false;   }   int n, m;   vector<point> a, b;   int main() {     read(n), read(m);     for (int i = 0, x, y; i < n; ++i) read(x), read(y), a.push_back(point(x, y));     for (int i = 0, x, y; i < m; ++i) read(x), read(y), b.push_back(point(x, y));     if (n == 1 || m == 1) return puts( YES ), 0;     puts((solve(a, b) || solve(b, a)) ?  YES  :  NO );     return 0;   }