#include <bits/stdc++.h>
using namespace std;
vector<pair<int, int>> av, bv;
int x[100010], y[100010], z[100010], w[100010];
priority_queue<pair<int, int>> que;
set<pair<int, int>> s;
using ll = long long;
ll n, seg1[200010], seg2[200010], mxx = 100000000000000;
void mnupdate(int p, ll a) {
  for (seg1[p += n] = a; p > 1; p >>= 1) {
    seg1[p >> 1] = min(seg1[p], seg1[p ^ 1]);
  }
}
ll mnquery(int l, int r) {
  ll mn = mxx;
  for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
    if (l & 1) mn = min(mn, seg1[l++]);
    if (r & 1) mn = min(mn, seg1[--r]);
  }
  return mn;
}
void mxupdate(int p, ll a) {
  for (seg2[p += n] = a; p > 1; p >>= 1) {
    seg2[p >> 1] = max(seg2[p], seg2[p ^ 1]);
  }
}
ll mxquery(int l, int r) {
  ll mn = -1;
  for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
    if (l & 1) mn = max(mn, seg2[l++]);
    if (r & 1) mn = max(mn, seg2[--r]);
  }
  return mn;
}
int main() {
  int i;
  cin >> n;
  for (i = 0; i < n; i++) {
    cin >> x[i] >> y[i] >> z[i] >> w[i];
    av.push_back({x[i], i});
    bv.push_back({z[i], i});
  }
  sort(av.begin(), av.end());
  sort(bv.begin(), bv.end());
  for (i = 0; i <= 2 * n; i++) {
    seg1[i] = mxx;
  }
  for (i = 0; i < n; i++) {
    int ind = av[i].second;
    mnupdate(ind, w[ind]);
    mxupdate(ind, z[ind]);
    s.insert({y[ind], ind});
    while (s.size()) {
      auto it = s.begin();
      int val = (*it).first, j = (*it).second;
      if (val < x[ind]) {
        mnupdate(j, mxx);
        mxupdate(j, -1);
        s.erase(it);
      } else {
        break;
      }
    }
    if (mxquery(0, n) > w[ind] || mnquery(0, n) < z[ind]) {
      cout << "NO" << endl;
      return 0;
    }
  }
  for (i = 0; i <= 2 * n; i++) {
    seg1[i] = mxx;
    seg2[i] = 0;
  }
  s.clear();
  for (i = 0; i < n; i++) {
    int ind = bv[i].second;
    mxupdate(ind, x[ind]);
    mnupdate(ind, y[ind]);
    s.insert({w[ind], ind});
    while (s.size()) {
      auto it = s.begin();
      int val = (*it).first, j = (*it).second;
      if (val < z[ind]) {
        mnupdate(j, mxx);
        mxupdate(j, -1);
        s.erase(it);
      } else {
        break;
      }
    }
    if (mxquery(0, n) > y[ind] || mnquery(0, n) < x[ind]) {
      cout << "NO" << endl;
      return 0;
    }
  }
  cout << "YES" << endl;
}
