#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n;
const int inf = 1e9;
struct Q {
  int x1, y1, x2, y2;
} q[N];
struct Edge {
  int x, y, p;
};
const bool operator<(Edge a, Edge b) {
  if (a.x != b.x)
    return a.x < b.x;
  else if (a.y != b.y)
    return a.y < b.y;
  else
    return a.p < b.p;
}
set<Edge> e[4];
bool work(set<Edge> e[], int n) {
  if (n == 1) return 1;
  int maxn[4] = {-inf, -inf, -inf, -inf};
  set<Edge>::iterator it[4];
  for (int i = 0; i < 4; i++) it[i] = e[i].begin();
  set<Edge> tmp[4];
  for (int j = 0; j < 4; j++) tmp[j].clear();
  for (int i = 0; i < n; i++)
    for (int j = 0; j < 4; j++) {
      vector<int> num;
      if (it[j]->x >= maxn[j] && maxn[j] != -inf) {
        vector<int> v;
        set<Edge>::iterator k;
        for (k = e[j].begin(); k != it[j]; k++) v.push_back(k->p);
        int len = v.size();
        for (int r = 0; r < len; r++) {
          int u = v[r];
          e[0].erase((Edge){q[u].x1, q[u].x2, u});
          e[1].erase((Edge){-q[u].x2, -q[u].x1, u});
          e[2].erase((Edge){q[u].y1, q[u].y2, u});
          e[3].erase((Edge){-q[u].y2, -q[u].y1, u});
          tmp[0].insert((Edge){q[u].x1, q[u].x2, u});
          tmp[1].insert((Edge){-q[u].x2, -q[u].x1, u});
          tmp[2].insert((Edge){q[u].y1, q[u].y2, u});
          tmp[3].insert((Edge){-q[u].y2, -q[u].y1, u});
        }
        return work(e, n - len) && work(tmp, len);
      }
      maxn[j] = max(maxn[j], it[j]->y);
      it[j]++;
    }
  return 0;
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    int x1, y1, x2, y2;
    scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
    q[i] = (Q){x1, y1, x2, y2};
    e[0].insert((Edge){x1, x2, i});
    e[1].insert((Edge){-x2, -x1, i});
    e[2].insert((Edge){y1, y2, i});
    e[3].insert((Edge){-y2, -y1, i});
  }
  if (work(e, n))
    printf("YES");
  else
    printf("NO");
}
