#include <bits/stdc++.h>
using namespace std;
const int SIZE = 100000 + 5;
const int INF = 2e9;
struct Node {
  int x, y, ind;
  bool operator<(const Node &nd) const {
    if (x != nd.x) return x < nd.x;
    if (y != nd.y) return y < nd.y;
    return ind < nd.ind;
  }
};
set<Node> st[4];
int ndx[SIZE][4], ndy[SIZE][4];
inline int getint(void) {
  register int x = 0, ch = getchar();
  for (; ch < '0' || ch > '9'; ch = getchar())
    ;
  for (; ch >= '0' && ch <= '9';
       x = (x << 1) + (x << 3) + (ch - '0'), ch = getchar())
    ;
  return x;
}
int solve(set<Node> st[4]) {
  if (st[0].size() == 1) return 1;
  set<Node>::iterator it[4];
  const int sz = st[0].size();
  int maxi[4];
  for (int i = 0; i < 4; ++i) maxi[i] = -INF, it[i] = st[i].begin();
  for (int i = 1; i < sz; ++i)
    for (int j = 0; j < 4; ++j) {
      maxi[j] = max(maxi[j], it[j]->y), ++it[j];
      if (it[j]->x >= maxi[j]) {
        set<Node> nxt[4];
        for (set<Node>::iterator tmp = st[j].begin(); tmp != it[j];) {
          const int id = tmp->ind;
          ++tmp;
          for (int k = 0; k < 4; ++k) {
            Node x = (Node){ndx[id][k], ndy[id][k], id};
            nxt[k].insert(x), st[k].erase(x);
          }
        }
        return solve(nxt) && solve(st);
      }
    }
  return 0;
}
int main(void) {
  int n = getint();
  for (register int i = 1; i <= n; ++i) {
    int a, b, c, d;
    scanf("%d%d%d%d", &a, &b, &c, &d);
    ndx[i][0] = a, ndy[i][0] = c, st[0].insert((Node){a, c, i});
    ndx[i][1] = -c, ndy[i][1] = -a, st[1].insert((Node){-c, -a, i});
    ndx[i][2] = b, ndy[i][2] = d, st[2].insert((Node){b, d, i});
    ndx[i][3] = -d, ndy[i][3] = -b, st[3].insert((Node){-d, -b, i});
  }
  puts(solve(st) ? "YES" : "NO");
  return 0;
}
