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.

import java.util.*;
import java.io.*;
import java.math.*;

public class D {
    static PrintWriter out;
    static BufferedReader in;
    static StringTokenizer stk;

        static class Triple implements Comparable<Triple> {

        int a, b, c;

        Triple(int a, int b, int c){
             this.a = a;
             this.b = b;
             this.c = c;
         }
         public int compareTo(Triple o) {
             return Integer.compare(a * 2 + b, o.a * 2 + o.b);
         }

     }
    
    static class Rect {
        int as, ae, bs, be;
     
        public Rect(int as, int ae, int bs, int be) {
            this.as = as;
            this.ae = ae;
            this.bs = bs;
            this.be = be;
        }
    }
    


    
    public static void main(String[] args) throws Exception {
        out = new PrintWriter(new OutputStreamWriter(System.out));
        in = new BufferedReader(new InputStreamReader(System.in));

        // Start of User Code

        int n = ni();
        Rect[] r = new Rect[n];
        Triple[] evt = new Triple[2*n];
        
        TreeMap<Integer,Integer> starts = new TreeMap<>();
        TreeMap<Integer,Integer> ends = new TreeMap<>();
        
        boolean ok = true;
 
        for (int i = 0; i < n; i++) {
            int as, ae, bs, be;
            as = ni();
            ae = ni();
            bs = ni();
            be = ni();
            r[i] = new Rect(as, ae, bs, be);
            evt[2*i] = new Triple(as, 0, i);
            evt[2*i+1] = new Triple(ae,1, i);
        }
        
       Arrays.sort(evt);
       
       for(Triple e: evt){
           Rect s = r[e.c];
           if(e.b == 0){
           
               // check for badness
               if(starts.ceilingKey(s.be + 1) != null) ok = false;
               if(ends.floorKey(s.bs - 1) != null) ok = false;
               // add rectangle
               
               if(!starts.containsKey(s.bs)) starts.put(s.bs, 0);
               starts.put(s.bs, starts.get(s.bs) + 1);
               
               if(!ends.containsKey(s.be)) ends.put(s.be, 0);
               ends.put(s.be, ends.get(s.be) + 1);
           }else{
               // remove rectangle

               int t;
               t = starts.get(s.bs) - 1;
               if(t == 0) starts.remove(s.bs);
               else starts.put(s.bs, t);
               t = ends.get(s.be) - 1;
               if(t == 0) ends.remove(s.be);
               else ends.put(s.be, t);
           }
       }
       
       
       for (int i = 0; i < n; i++) {
            r[i] = new Rect(r[i].bs, r[i].be, r[i].as, r[i].ae);
            evt[2*i] = new Triple(r[i].as, 0, i);
            evt[2*i+1] = new Triple(r[i].ae,1, i);
        }
        
       Arrays.sort(evt);
       
       for(Triple e: evt){
           Rect s = r[e.c];
           if(e.b == 0){
           
               // check for badness
               if(starts.ceilingKey(s.be + 1) != null) ok = false;
               if(ends.floorKey(s.bs - 1) != null) ok = false;
               // add rectangle
               
               if(!starts.containsKey(s.bs)) starts.put(s.bs, 0);
               starts.put(s.bs, starts.get(s.bs) + 1);
               
               if(!ends.containsKey(s.be)) ends.put(s.be, 0);
               ends.put(s.be, ends.get(s.be) + 1);
           }else{
               // remove rectangle

               int t;
               t = starts.get(s.bs) - 1;
               if(t == 0) starts.remove(s.bs);
               else starts.put(s.bs, t);
               t = ends.get(s.be) - 1;
               if(t == 0) ends.remove(s.be);
               else ends.put(s.be, t);
           }
       }
       
       if(ok) System.out.println("YES");
       else System.out.println("NO");

        // End of User Code
        out.flush();
        in.close();
    }

    static String proc() throws Exception {
        throw new Exception("NOT IMPLEMENTED YET");
    }

    static long modPow(long n, long pow, long mod) {
        return BigInteger.valueOf(n).modPow(BigInteger.valueOf(pow), BigInteger.valueOf(mod)).longValue();
    }

    static long modInv(long n, long mod, boolean isPrimeModuli) {
        if (isPrimeModuli) {
            return modPow(n, mod - 2, mod);
        }
        return BigInteger.valueOf(n).modInverse(BigInteger.valueOf(mod)).longValue();
    }
    // calc factorials
    static long[] fact;

    static void calcFactorials(int n) {
        fact = new long[n + 1];
        fact[0] = 1;
        for (int i = 1; i <= n; i++) {
            fact[i] = fact[i - 1] * i;
        }
    }

    static void calcFactorialsModM(int n, long M) {
        fact = new long[n + 1];
        fact[0] = 1;
        for (int i = 1; i <= n; i++) {
            fact[i] = fact[i - 1] * i;
            fact[i] %= M;
        }
    }

    static long ncr(int n, int r) {
        return fact[n] / (fact[n - r] * fact[r]);
    }

    static long ncrModM(int n, int r, long MOD, boolean isPrimeModuli) {
        return (((fact[n] * modInv(fact[n - r], MOD, isPrimeModuli))%MOD)* modInv(fact[r], MOD, isPrimeModuli))%MOD;
    }

    static long toL(String s) {
        return Long.parseLong(s);
    }

    static long toL(BigInteger n) {
        return n.longValue();
    }

    static int toI(String s) {
        return Integer.parseInt(s);
    }

    static double toD(String s) {
        return Double.parseDouble(s);
    }

    static void printf(String format, Object... args) {
        out.printf(format, args);
    }
    

    static int ni() throws Exception {
        while (stk == null || !stk.hasMoreTokens()) {
            stk = new StringTokenizer(in.readLine());
        }
        return Integer.parseInt(stk.nextToken());
    }

    static long nl() throws Exception {
        while (stk == null || !stk.hasMoreTokens()) {
            stk = new StringTokenizer(in.readLine());
        }
        return Long.parseLong(stk.nextToken());
    }

    static double nd() throws Exception {
        while (stk == null || !stk.hasMoreTokens()) {
            stk = new StringTokenizer(in.readLine());
        }
        return Double.parseDouble(stk.nextToken());
    }

    static String ns() throws Exception {
        while (stk == null || !stk.hasMoreTokens()) {
            stk = new StringTokenizer(in.readLine());
        }
        return stk.nextToken();
    }

    static int min(int a, int b) {
        return a < b ? a : b;
    }

    static int max(int a, int b) {
        return a > b ? a : b;
    }

    static long min(long a, long b) {
        return a < b ? a : b;
    }

    static long max(long a, long b) {
        return a > b ? a : b;
    }

    static int gcd(int a, int b) {
        if (b == 0) {
            return a;
        }
        return gcd(b, a % b);
    }

    static long gcd(long a, long b) {
        if (b == 0) {
            return a;
        }
        return gcd(b, a % b);
    }
}
