#include <bits/stdc++.h>
#pragma GCC optimize("Ofast,unroll-all-loops")
using namespace std;
void ans(int code = 0) {
  if (code) {
    cout << "YES" << endl;
  } else {
    cout << "NO" << endl;
  }
  exit(0);
}
int get_idx(int x, const vector<int> &vals) {
  return lower_bound((vals).begin(), (vals).end(), x) - vals.begin();
}
void compress(int &x, const vector<int> &vals) { x = get_idx(x, vals); }
struct Segtree {
  int n;
  vector<char> part, full;
  Segtree(int nn) : n(nn) {
    part.resize(5 * n);
    full.resize(5 * n);
  }
  void push(int x, int l, int r) {
    if (full[x] && r - l > 1) {
      full[2 * x + 1] = 1;
      full[2 * x + 2] = 1;
    }
  }
  void update(int x, int l, int r, int ql, int qr) {
    push(x, l, r);
    if (ql >= r || l >= qr) return;
    if (ql <= l && r <= qr) {
      full[x] = part[x] = 1;
      push(x, l, r);
      return;
    }
    int c = (l + r) / 2;
    update(2 * x + 1, l, c, ql, qr);
    update(2 * x + 2, c, r, ql, qr);
    if (!part[x]) {
      part[x] = max(part[2 * x + 1], part[2 * x + 2]);
    }
  }
  void update(int ql, int qr) { update(0, 0, n, ql, qr); }
  int query(int x, int l, int r, int ql, int qr) {
    push(x, l, r);
    if (ql >= r || l >= qr) return 0;
    if (ql <= l && r <= qr) return part[x];
    int c = (l + r) / 2;
    return max(query(2 * x + 1, l, c, ql, qr), query(2 * x + 2, c, r, ql, qr));
  }
  int query(int ql, int qr) { return query(0, 0, n, ql, qr); }
};
const int MAXN = 2e5 + 10;
void super_solve(vector<pair<pair<int, int>, pair<int, int>>> v) {
  vector<int> vals;
  int n = (int)(v).size();
  for (int i = 0; i < n; ++i) {
    vals.push_back(v[i].second.first);
    vals.push_back(v[i].second.second);
  }
  sort((vals).begin(), (vals).end());
  vals.resize(unique((vals).begin(), (vals).end()) - vals.begin());
  for (int i = 0; i < n; ++i) {
    compress(v[i].second.first, vals);
    compress(v[i].second.second, vals);
  }
  Segtree st(MAXN);
  map<int, vector<pair<int, int>>> a_set, a_query;
  vector<int> xs;
  for (int i = 0; i < n; ++i) {
    a_set[v[i].first.second].push_back(
        {v[i].second.first, v[i].second.second + 1});
    a_query[v[i].first.first].push_back(
        {v[i].second.first, v[i].second.second + 1});
    xs.push_back(v[i].first.second);
    xs.push_back(v[i].first.first);
  }
  sort((xs).begin(), (xs).end());
  xs.resize(unique((xs).begin(), (xs).end()) - xs.begin());
  for (auto &elem : xs) {
    int cur_x = elem;
    for (auto &act : a_query[cur_x]) {
      if (st.query(act.first, act.second)) {
        ans();
      }
    }
    for (auto &act : a_set[cur_x]) {
      st.update(act.first, act.second);
    }
  }
}
const int MAXX = 1e9 + 10;
void solve(vector<pair<pair<int, int>, pair<int, int>>> v) {
  int n = (int)(v).size();
  super_solve(v);
  for (int i = 0; i < n; ++i) {
    v[i].first.first = MAXX - v[i].first.first;
    v[i].first.second = MAXX - v[i].first.second;
    swap(v[i].first.first, v[i].first.second);
  }
  super_solve(v);
}
void run() {
  int n;
  cin >> n;
  vector<pair<pair<int, int>, pair<int, int>>> v(n);
  for (int i = 0; i < n; ++i) {
    cin >> v[i].first.first >> v[i].first.second;
    cin >> v[i].second.first >> v[i].second.second;
  }
  solve(v);
  for (int i = 0; i < n; ++i) {
    swap(v[i].first.first, v[i].second.first);
    swap(v[i].first.second, v[i].second.second);
  }
  solve(v);
  ans(1);
}
signed main() {
  std::ios_base::sync_with_stdio(0);
  std::cin.tie(0);
  run();
}
