#include <bits/stdc++.h>
using namespace std;
vector<long int> reverse_edge = {2, 3, 0, 1};
bool check_split(vector<vector<long int>> &v) {
  long int amount = v.size();
  if (amount <= 1) return true;
  unordered_set<long int> deleted;
  vector<list<vector<long int>>> vv(4, list<vector<long int>>(v.size()));
  for (long int i = 0; i < 4; i++) {
    sort(v.begin(), v.end(), [i](vector<long int> &v1, vector<long int> &v2) {
      if (i > 1) return v1[i] > v2[i];
      return v1[i] < v2[i];
    });
    copy(v.begin(), v.end(), vv[i].begin());
  }
  vector<long int> maximums(4);
point:
  for (long int i = 0; i < 4; i++) {
    auto itr_cur = vv[i].begin();
    while (deleted.find((*itr_cur)[4]) != deleted.end()) {
      auto itr_prev = itr_cur;
      ++itr_cur;
      vv[i].erase(itr_prev);
    }
    maximums[i] = (*itr_cur)[reverse_edge[i]];
  }
  vector<list<vector<long int>>::iterator> iterators;
  for (long int i = 0; i < 4; i++) {
    iterators.push_back(vv[i].begin());
  }
  for (long int i = 1; i < amount; i++) {
    for (long int j = 0; j < 2; j++) {
      ++iterators[j];
      while (deleted.find((*iterators[j])[4]) != deleted.end()) {
        auto prev = iterators[j];
        ++iterators[j];
        vv[j].erase(prev);
      }
      if ((*iterators[j])[j] >= maximums[j]) {
        vector<vector<long int>> new_vec;
        for (auto itr = vv[j].begin(); itr != iterators[j]; itr++) {
          deleted.insert((*itr)[4]);
          new_vec.push_back(*itr);
        }
        amount -= new_vec.size();
        if (!check_split(new_vec)) return false;
        if (amount <= 1)
          return true;
        else
          goto point;
      } else {
        maximums[j] = max(maximums[j], (*iterators[j])[reverse_edge[j]]);
      }
    }
    for (long int j = 2; j < 4; j++) {
      ++iterators[j];
      while (deleted.find((*iterators[j])[4]) != deleted.end()) {
        auto prev = iterators[j];
        ++iterators[j];
        vv[j].erase(prev);
      }
      if ((*iterators[j])[j] <= maximums[j]) {
        vector<vector<long int>> new_vec;
        for (auto itr = vv[j].begin(); itr != iterators[j]; itr++) {
          deleted.insert((*itr)[4]);
          new_vec.push_back(*itr);
        }
        amount -= new_vec.size();
        if (!check_split(new_vec)) return false;
        if (amount <= 1)
          return true;
        else
          goto point;
      } else {
        maximums[j] = min(maximums[j], (*iterators[j])[reverse_edge[j]]);
      }
    }
  }
  return false;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  long int n;
  cin >> n;
  vector<vector<long int>> v(n, {0, 0, 0, 0, 0});
  for (long int i = 0; i < n; i++) {
    for (long int j = 0; j < 4; j++) cin >> v[i][j];
    v[i][4] = i;
  }
  string ans = "NO";
  if (check_split(v)) ans = "YES";
  cout << ans;
}
