#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization("unroll-loops")
using namespace std;
template <class T>
inline T sqr(T x) {
  return x * x;
}
template <class T>
inline T parse(const string &s) {
  T x;
  stringstream ss(s);
  ss >> x;
  return x;
}
const long double EPS = 1e-12;
const int INF = 1000 * 1000 * 1000;
const long long LINF = INF * 1ll * INF;
const long double DINF = 1e200;
const long double PI = 3.1415926535897932384626433832795l;
int gcd(int a, int b) { return a ? gcd(b % a, a) : b; }
long long gcd(long long a, long long b) { return a ? gcd(b % a, a) : b; }
long long gcdex(long long a, long long b, long long &x, long long &y) {
  if (!a) {
    x = 0, y = 1;
    return b;
  }
  long long k = b / a;
  long long g = gcdex(b - k * a, a, y, x);
  x -= k * y;
  return g;
}
long long inv(long long a, long long m) {
  assert(m > 1);
  long long x, y, g;
  g = gcdex(a, m, x, y);
  return (x % (m / g) + m / g) % m / g;
}
long long crt(long long a1, long long m1, long long a2, long long m2) {
  long long a = (a2 - a1 % m2 + m2) % m2;
  long long x, y, g;
  g = gcdex(m1, m2, x, y);
  if (a % g) return -1;
  long long m = m1 / g * m2;
  assert(x + m2 >= 0);
  x = a / g * (x + m2) % m2;
  long long r = (a1 + x * m1) % m;
  assert(r % m1 == a1 && r % m2 == a2);
  return r;
}
long long powmod(long long a, long long p, long long m) {
  assert(p >= 0);
  long long r = 1;
  while (p) {
    if (p & 1) r = r * a % m;
    p >>= 1;
    a = a * a % m;
  }
  return r;
}
bool isprime(long long a) {
  if (a <= 1) return false;
  for (long long i = 2; i * i <= a; ++i) {
    if (a % i == 0) return false;
  }
  return true;
}
long long sqrtup(long long a) {
  if (!a) return 0;
  long long x = max(0ll, (long long)sqrt((long double)a));
  while (x * x >= a) --x;
  while ((x + 1) * (x + 1) < a) ++x;
  return x + 1;
}
long long isqrt(long long a) {
  if (a <= 0) {
    assert(!a);
    return 0;
  }
  long long x = (long long)sqrt((long double)a);
  while (sqr(x + 1) <= a) ++x;
  while (x * x > a) --x;
  return x;
}
long long sgn(long long x) { return x < 0 ? -1 : x > 0 ? 1 : 0; }
long double randf() {
  long double m = RAND_MAX + 1.;
  return (((rand() + .5) / m + rand()) / m + rand()) / m;
}
template <class T>
ostream &operator<<(ostream &s, const vector<T> &v);
template <class A, class B>
ostream &operator<<(ostream &s, const pair<A, B> &p);
template <class K, class V>
ostream &operator<<(ostream &s, const map<K, V> &m);
template <class T>
ostream &operator<<(ostream &s, const set<T> &m);
template <class T, size_t N>
ostream &operator<<(ostream &s, const array<T, N> &a);
template <class... T>
ostream &operator<<(ostream &s, const tuple<T...> &t);
template <class T>
ostream &operator<<(ostream &s, const vector<T> &v) {
  s << '[';
  for (int i = 0; i < (((int)(v).size())); ++i) {
    if (i) s << ',';
    s << v[i];
  }
  s << ']';
  return s;
}
template <class A, class B>
ostream &operator<<(ostream &s, const pair<A, B> &p) {
  s << "(" << p.first << "," << p.second << ")";
  return s;
}
template <class K, class V>
ostream &operator<<(ostream &s, const map<K, V> &m) {
  s << "{";
  bool f = false;
  for (const auto &it : m) {
    if (f) s << ",";
    f = true;
    s << it.first << ": " << it.second;
  }
  s << "}";
  return s;
}
template <class T>
ostream &operator<<(ostream &s, const set<T> &m) {
  s << "{";
  bool f = false;
  for (const auto &it : m) {
    if (f) s << ",";
    f = true;
    s << it;
  }
  s << "}";
  return s;
}
template <class T>
ostream &operator<<(ostream &s, const multiset<T> &m) {
  s << "{";
  bool f = false;
  for (const auto &it : m) {
    if (f) s << ",";
    f = true;
    s << it;
  }
  s << "}";
  return s;
}
template <class T, class V, class C>
ostream &operator<<(ostream &s, const priority_queue<T, V, C> &q) {
  auto a = q;
  s << "{";
  bool f = false;
  while (!a.empty()) {
    if (f) s << ",";
    f = true;
    s << a.top();
    a.pop();
  }
  return s << "}";
}
template <class T, size_t N>
ostream &operator<<(ostream &s, const array<T, N> &a) {
  s << '[';
  for (int i = 0; i < (((int)(a).size())); ++i) {
    if (i) s << ',';
    s << a[i];
  }
  s << ']';
  return s;
}
template <class T>
ostream &operator<<(ostream &s, const deque<T> &a) {
  s << '[';
  for (int i = 0; i < (((int)(a).size())); ++i) {
    if (i) s << ',';
    s << a[i];
  }
  s << ']';
  return s;
}
template <size_t n, class... T>
struct put1 {
  static ostream &put(ostream &s, const tuple<T...> &t) {
    s << get<sizeof...(T) - n>(t);
    if (n > 1) s << ',';
    return put1<n - 1, T...>::put(s, t);
  }
};
template <class... T>
struct put1<0, T...> {
  static ostream &put(ostream &s, const tuple<T...> &t) { return s; }
};
template <class... T>
ostream &operator<<(ostream &s, const tuple<T...> &t) {
  s << "(";
  put1<sizeof...(T), T...>::put(s, t);
  s << ")";
  return s;
}
ostream &put3(ostream &s, const char *, bool) { return s; }
template <class U, class... T>
ostream &put3(ostream &s, const char *f, bool fs, U &&u, T &&...t) {
  while (*f == ' ') ++f;
  if (!fs) s << ", ";
  auto nf = f;
  int d = 0;
  while (*nf && (*nf != ',' || d)) {
    if (*nf == '(')
      ++d;
    else if (*nf == ')')
      --d;
    ++nf;
  }
  auto nf2 = nf;
  while (nf2 > f && *(nf2 - 1) == ' ') --nf;
  fs = *f == '"';
  if (!fs) {
    s.write(f, nf2 - f);
    s << "=";
  };
  s << u;
  if (fs) s << ' ';
  if (*nf) ++nf;
  return put3(s, nf, fs, forward<T>(t)...);
}
vector<pair<pair<int, int>, pair<int, int>>> R;
void flip() {
  for (auto &p : R) {
    swap(p.first, p.second);
  }
}
struct ranges {
  set<pair<int, int>> S;
  bool inters(pair<int, int> p) const {
    auto it = S.upper_bound(make_pair(p.second, +INF * 2));
    if (it == S.begin()) return false;
    --it;
    assert(it->first <= p.second);
    return it->second >= p.first;
  }
  void add(pair<int, int> p) {
    auto it2 = S.upper_bound(make_pair(p.second + 1, +INF * 2));
    while (it2 != S.begin()) {
      --it2;
      assert(it2->first <= p.second + 1);
      if (it2->second < p.first - 1) break;
      p.first = it2->first;
      it2 = S.erase(it2);
    }
    assert(!inters(p));
    S.insert(p);
  }
};
bool doit() {
  vector<pair<pair<int, int>, pair<int, int>>> E;
  for (const auto &p : R) {
    E.push_back(make_pair(make_pair(p.second.first, -1), p.first));
    E.push_back(make_pair(make_pair(p.second.second, +1), p.first));
  }
  sort((E).begin(), (E).end());
  ranges r;
  for (auto &e : E) {
    if (e.first.second == -1) {
      if (r.inters(e.second)) return false;
    } else {
      r.add(e.second);
    }
  }
  return true;
}
int main(int argc, char **argv) {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.precision(20);
  srand(35964);
  int n;
  cin >> n;
  R.resize(n);
  for (int i = 0; i < (n); ++i)
    cin >> R[i].first.first >> R[i].first.second >> R[i].second.first >>
        R[i].second.second;
  for (int q = 0; q < (2); ++q) {
    do {
    } while (false);
    if (!doit()) {
      cout << "NO";
      return 0;
    }
    flip();
  }
  cout << "YES";
  return 0;
}

### Prompt

Create a solution in CPP for the following problem:

Filled with optimism, Hyunuk will host a conference about how great this new year will be!

The conference will have n lectures. Hyunuk has two candidate venues a and b. For each of the n lectures, the speaker specified two time intervals [sa_i, ea_i] (sa_i ≤ ea_i) and [sb_i, eb_i] (sb_i ≤ eb_i). If the conference is situated in venue a, the lecture will be held from sa_i to ea_i, and if the conference is situated in venue b, the lecture will be held from sb_i to eb_i. Hyunuk will choose one of these venues and all lectures will be held at that venue.

Two lectures are said to overlap if they share any point in time in common. Formally, a lecture held in interval [x, y] overlaps with a lecture held in interval [u, v] if and only if max(x, u) ≤ min(y, v).

We say that a participant can attend a subset s of the lectures if the lectures in s do not pairwise overlap (i.e. no two lectures overlap). Note that the possibility of attending may depend on whether Hyunuk selected venue a or venue b to hold the conference.

A subset of lectures s is said to be venue-sensitive if, for one of the venues, the participant can attend s, but for the other venue, the participant cannot attend s.

A venue-sensitive set is problematic for a participant who is interested in attending the lectures in s because the participant cannot be sure whether the lecture times will overlap. Hyunuk will be happy if and only if there are no venue-sensitive sets. Determine whether Hyunuk will be happy.

Input

The first line contains an integer n (1 ≤ n ≤ 100 000), the number of lectures held in the conference.

Each of the next n lines contains four integers sa_i, ea_i, sb_i, eb_i (1 ≤ sa_i, ea_i, sb_i, eb_i ≤ 10^9, sa_i ≤ ea_i, sb_i ≤ eb_i).

Output

Print "YES" if Hyunuk will be happy. Print "NO" otherwise.

You can print each letter in any case (upper or lower).

Examples

Input


2
1 2 3 6
3 4 7 8


Output


YES


Input


3
1 3 2 4
4 5 6 7
3 4 5 5


Output


NO


Input


6
1 5 2 9
2 4 5 8
3 6 7 11
7 10 12 16
8 11 13 17
9 12 14 18


Output


YES

Note

In second example, lecture set \{1, 3\} is venue-sensitive. Because participant can't attend this lectures in venue a, but can attend in venue b.

In first and third example, venue-sensitive set does not exist.

### Response

```cpp
#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization("unroll-loops")
using namespace std;
template <class T>
inline T sqr(T x) {
  return x * x;
}
template <class T>
inline T parse(const string &s) {
  T x;
  stringstream ss(s);
  ss >> x;
  return x;
}
const long double EPS = 1e-12;
const int INF = 1000 * 1000 * 1000;
const long long LINF = INF * 1ll * INF;
const long double DINF = 1e200;
const long double PI = 3.1415926535897932384626433832795l;
int gcd(int a, int b) { return a ? gcd(b % a, a) : b; }
long long gcd(long long a, long long b) { return a ? gcd(b % a, a) : b; }
long long gcdex(long long a, long long b, long long &x, long long &y) {
  if (!a) {
    x = 0, y = 1;
    return b;
  }
  long long k = b / a;
  long long g = gcdex(b - k * a, a, y, x);
  x -= k * y;
  return g;
}
long long inv(long long a, long long m) {
  assert(m > 1);
  long long x, y, g;
  g = gcdex(a, m, x, y);
  return (x % (m / g) + m / g) % m / g;
}
long long crt(long long a1, long long m1, long long a2, long long m2) {
  long long a = (a2 - a1 % m2 + m2) % m2;
  long long x, y, g;
  g = gcdex(m1, m2, x, y);
  if (a % g) return -1;
  long long m = m1 / g * m2;
  assert(x + m2 >= 0);
  x = a / g * (x + m2) % m2;
  long long r = (a1 + x * m1) % m;
  assert(r % m1 == a1 && r % m2 == a2);
  return r;
}
long long powmod(long long a, long long p, long long m) {
  assert(p >= 0);
  long long r = 1;
  while (p) {
    if (p & 1) r = r * a % m;
    p >>= 1;
    a = a * a % m;
  }
  return r;
}
bool isprime(long long a) {
  if (a <= 1) return false;
  for (long long i = 2; i * i <= a; ++i) {
    if (a % i == 0) return false;
  }
  return true;
}
long long sqrtup(long long a) {
  if (!a) return 0;
  long long x = max(0ll, (long long)sqrt((long double)a));
  while (x * x >= a) --x;
  while ((x + 1) * (x + 1) < a) ++x;
  return x + 1;
}
long long isqrt(long long a) {
  if (a <= 0) {
    assert(!a);
    return 0;
  }
  long long x = (long long)sqrt((long double)a);
  while (sqr(x + 1) <= a) ++x;
  while (x * x > a) --x;
  return x;
}
long long sgn(long long x) { return x < 0 ? -1 : x > 0 ? 1 : 0; }
long double randf() {
  long double m = RAND_MAX + 1.;
  return (((rand() + .5) / m + rand()) / m + rand()) / m;
}
template <class T>
ostream &operator<<(ostream &s, const vector<T> &v);
template <class A, class B>
ostream &operator<<(ostream &s, const pair<A, B> &p);
template <class K, class V>
ostream &operator<<(ostream &s, const map<K, V> &m);
template <class T>
ostream &operator<<(ostream &s, const set<T> &m);
template <class T, size_t N>
ostream &operator<<(ostream &s, const array<T, N> &a);
template <class... T>
ostream &operator<<(ostream &s, const tuple<T...> &t);
template <class T>
ostream &operator<<(ostream &s, const vector<T> &v) {
  s << '[';
  for (int i = 0; i < (((int)(v).size())); ++i) {
    if (i) s << ',';
    s << v[i];
  }
  s << ']';
  return s;
}
template <class A, class B>
ostream &operator<<(ostream &s, const pair<A, B> &p) {
  s << "(" << p.first << "," << p.second << ")";
  return s;
}
template <class K, class V>
ostream &operator<<(ostream &s, const map<K, V> &m) {
  s << "{";
  bool f = false;
  for (const auto &it : m) {
    if (f) s << ",";
    f = true;
    s << it.first << ": " << it.second;
  }
  s << "}";
  return s;
}
template <class T>
ostream &operator<<(ostream &s, const set<T> &m) {
  s << "{";
  bool f = false;
  for (const auto &it : m) {
    if (f) s << ",";
    f = true;
    s << it;
  }
  s << "}";
  return s;
}
template <class T>
ostream &operator<<(ostream &s, const multiset<T> &m) {
  s << "{";
  bool f = false;
  for (const auto &it : m) {
    if (f) s << ",";
    f = true;
    s << it;
  }
  s << "}";
  return s;
}
template <class T, class V, class C>
ostream &operator<<(ostream &s, const priority_queue<T, V, C> &q) {
  auto a = q;
  s << "{";
  bool f = false;
  while (!a.empty()) {
    if (f) s << ",";
    f = true;
    s << a.top();
    a.pop();
  }
  return s << "}";
}
template <class T, size_t N>
ostream &operator<<(ostream &s, const array<T, N> &a) {
  s << '[';
  for (int i = 0; i < (((int)(a).size())); ++i) {
    if (i) s << ',';
    s << a[i];
  }
  s << ']';
  return s;
}
template <class T>
ostream &operator<<(ostream &s, const deque<T> &a) {
  s << '[';
  for (int i = 0; i < (((int)(a).size())); ++i) {
    if (i) s << ',';
    s << a[i];
  }
  s << ']';
  return s;
}
template <size_t n, class... T>
struct put1 {
  static ostream &put(ostream &s, const tuple<T...> &t) {
    s << get<sizeof...(T) - n>(t);
    if (n > 1) s << ',';
    return put1<n - 1, T...>::put(s, t);
  }
};
template <class... T>
struct put1<0, T...> {
  static ostream &put(ostream &s, const tuple<T...> &t) { return s; }
};
template <class... T>
ostream &operator<<(ostream &s, const tuple<T...> &t) {
  s << "(";
  put1<sizeof...(T), T...>::put(s, t);
  s << ")";
  return s;
}
ostream &put3(ostream &s, const char *, bool) { return s; }
template <class U, class... T>
ostream &put3(ostream &s, const char *f, bool fs, U &&u, T &&...t) {
  while (*f == ' ') ++f;
  if (!fs) s << ", ";
  auto nf = f;
  int d = 0;
  while (*nf && (*nf != ',' || d)) {
    if (*nf == '(')
      ++d;
    else if (*nf == ')')
      --d;
    ++nf;
  }
  auto nf2 = nf;
  while (nf2 > f && *(nf2 - 1) == ' ') --nf;
  fs = *f == '"';
  if (!fs) {
    s.write(f, nf2 - f);
    s << "=";
  };
  s << u;
  if (fs) s << ' ';
  if (*nf) ++nf;
  return put3(s, nf, fs, forward<T>(t)...);
}
vector<pair<pair<int, int>, pair<int, int>>> R;
void flip() {
  for (auto &p : R) {
    swap(p.first, p.second);
  }
}
struct ranges {
  set<pair<int, int>> S;
  bool inters(pair<int, int> p) const {
    auto it = S.upper_bound(make_pair(p.second, +INF * 2));
    if (it == S.begin()) return false;
    --it;
    assert(it->first <= p.second);
    return it->second >= p.first;
  }
  void add(pair<int, int> p) {
    auto it2 = S.upper_bound(make_pair(p.second + 1, +INF * 2));
    while (it2 != S.begin()) {
      --it2;
      assert(it2->first <= p.second + 1);
      if (it2->second < p.first - 1) break;
      p.first = it2->first;
      it2 = S.erase(it2);
    }
    assert(!inters(p));
    S.insert(p);
  }
};
bool doit() {
  vector<pair<pair<int, int>, pair<int, int>>> E;
  for (const auto &p : R) {
    E.push_back(make_pair(make_pair(p.second.first, -1), p.first));
    E.push_back(make_pair(make_pair(p.second.second, +1), p.first));
  }
  sort((E).begin(), (E).end());
  ranges r;
  for (auto &e : E) {
    if (e.first.second == -1) {
      if (r.inters(e.second)) return false;
    } else {
      r.add(e.second);
    }
  }
  return true;
}
int main(int argc, char **argv) {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.precision(20);
  srand(35964);
  int n;
  cin >> n;
  R.resize(n);
  for (int i = 0; i < (n); ++i)
    cin >> R[i].first.first >> R[i].first.second >> R[i].second.first >>
        R[i].second.second;
  for (int q = 0; q < (2); ++q) {
    do {
    } while (false);
    if (!doit()) {
      cout << "NO";
      return 0;
    }
    flip();
  }
  cout << "YES";
  return 0;
}

```