#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
const int MAXN = 100000;
struct Rect {
  int lx, ly, hx, hy, id;
};
bool operator<(const Rect &a, const Rect &b) { return a.lx < b.lx; }
struct LinkInfo {
  int prv[MAXN], nxt[MAXN];
};
struct LinkedList {
  int head, tail, sz;
  LinkedList() { head = -1, tail = -1, sz = 0; }
};
struct State {
  LinkedList lst[4];
};
LinkInfo link[4];
LinkInfo curlink[4];
int lval[MAXN][4];
int rval[MAXN][4];
int col[MAXN];
State clone(State orig) {
  for (int i = (0); i < (4); ++i)
    for (int x = orig.lst[i].head; x != -1; x = link[i].nxt[x])
      curlink[i].prv[x] = link[i].prv[x], curlink[i].nxt[x] = link[i].nxt[x];
  return orig;
}
void remove(LinkInfo &info, LinkedList &lst, int x) {
  --lst.sz;
  if (info.prv[x] == -1) {
    assert(lst.head == x);
    lst.head = info.nxt[x];
  } else
    info.nxt[info.prv[x]] = info.nxt[x];
  if (info.nxt[x] == -1) {
    assert(lst.tail == x);
    lst.tail = info.prv[x];
  } else
    info.prv[info.nxt[x]] = info.prv[x];
}
void append(LinkInfo &info, LinkedList &lst, int x) {
  ++lst.sz;
  info.prv[x] = lst.tail;
  info.nxt[x] = -1;
  lst.tail = x;
  if (info.prv[x] == -1) {
    assert(lst.head == -1);
    lst.head = x;
  } else
    info.nxt[info.prv[x]] = x;
}
void setcol(State &cur, int x, int c) {
  assert(col[x] == -1);
  col[x] = c;
  for (int i = (0); i < (4); ++i) remove(curlink[i], cur.lst[i], x);
}
void move(State &a, State &b, int i, int x) {
  remove(link[i], a.lst[i], x);
  append(link[i], b.lst[i], x);
}
bool solve(State orig) {
  State cur = clone(orig);
  for (int x = cur.lst[0].head; x != -1; x = curlink[0].nxt[x]) col[x] = -1;
  int ncol = 0;
  while (true) {
    int sz = cur.lst[0].sz;
    if (sz == 1) break;
    int at[4], mx[4];
    for (int i = (0); i < (4); ++i) at[i] = cur.lst[i].head, mx[i] = INT_MIN;
    bool found = false;
    for (int pos = (0); pos < (sz - 1); ++pos) {
      for (int i = (0); i < (4); ++i) {
        mx[i] = max(mx[i], rval[at[i]][i]);
        at[i] = curlink[i].nxt[at[i]];
        if (mx[i] <= lval[at[i]][i]) {
          int x = cur.lst[i].head;
          while (x != at[i]) {
            int y = curlink[i].nxt[x];
            setcol(cur, x, ncol);
            x = y;
          }
          ++ncol;
          found = true;
          break;
        }
      }
      if (found) break;
    }
    if (!found) return false;
  }
  vector<State> nstate(ncol);
  for (int i = (0); i < (4); ++i) {
    int x = orig.lst[i].head;
    while (x != -1) {
      int y = link[i].nxt[x];
      if (col[x] != -1) move(orig, nstate[col[x]], i, x);
      x = y;
    }
  }
  for (int i = (0); i < (((int)(nstate).size())); ++i)
    if (!solve(nstate[i])) return false;
  return true;
}
int n;
Rect rect[MAXN];
bool solve() {
  State all;
  for (int a = (0); a < (2); ++a) {
    for (int b = (0); b < (2); ++b) {
      sort(rect, rect + n);
      for (int i = (0); i < (n); ++i)
        lval[rect[i].id][2 * a + b] = rect[i].lx,
                                 rval[rect[i].id][2 * a + b] = rect[i].hx,
                                 append(link[2 * a + b], all.lst[2 * a + b],
                                        rect[i].id);
      for (int i = (0); i < (n); ++i)
        swap(rect[i].lx, rect[i].hx), rect[i].lx = -rect[i].lx,
                                      rect[i].hx = -rect[i].hx;
    }
    for (int i = (0); i < (n); ++i)
      swap(rect[i].lx, rect[i].ly), swap(rect[i].hx, rect[i].hy);
  }
  return solve(all);
}
void run() {
  scanf("%d", &n);
  for (int i = (0); i < (n); ++i)
    scanf("%d%d%d%d", &rect[i].lx, &rect[i].ly, &rect[i].hx, &rect[i].hy),
        rect[i].id = i;
  printf("%s\n", solve() ? "YES" : "NO");
}
int main() {
  run();
  return 0;
}
