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.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.Random;
import java.util.ArrayList;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.Collections;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, OutputWriter out) {
            int n = in.nextInt();
            ArrayList<Integer> perm = new ArrayList<>(), perm2 = new ArrayList<>();
            int[] a = new int[n];
            int[] b = new int[n];
            int[] c = new int[n];
            int[] d = new int[n];

            for (int i = 0; i < n; i++) {
                a[i] = in.nextInt() + 1;
                b[i] = in.nextInt() + 1;
                c[i] = in.nextInt() + 1;
                d[i] = in.nextInt() + 1;
                perm.add(i);
                perm2.add(i);
            }

            Collections.sort(perm, (i1, j1) -> {
                if (a[i1] < a[j1]) return -1;
                if (a[i1] > a[j1]) return 1;
                return 0;
            });


            Collections.sort(perm2, (i1, j1) -> {
                if (b[i1] < b[j1]) return -1;
                if (b[i1] > b[j1]) return 1;
                return 0;
            });


            int pos = 0;
            Treap.Node treap1 = null, treap2 = null;
            for (int i = 0; i < n; i++) {
                int ind = perm.get(i);
                while (pos < n && b[perm2.get(pos)] < a[ind]) {
                    // add to treap
                    int j = perm2.get(pos);
                    treap1 = Treap.insert(treap1, c[j], 1);
                    treap2 = Treap.insert(treap2, d[j], 1);
                    pos++;
                }
                int ALL = treap1 == null ? 0 : treap1.size;

                int l = c[ind], r = d[ind];
                // right end < l + left end > r
                if (Treap.query(treap1, r + 1, 1 << 30).sum + Treap.query(treap2, 0, l - 1).sum != ALL) {
                    out.println("NO");
                    return;
                }
            }

            for (int i = 0; i < n; i++) {
                int temp = a[i];
                a[i] = c[i];
                c[i] = temp;
                temp = b[i];
                b[i] = d[i];
                d[i] = temp;
            }

            Collections.sort(perm, (i1, j1) -> {
                if (a[i1] < a[j1]) return -1;
                if (a[i1] > a[j1]) return 1;
                return 0;
            });


            Collections.sort(perm2, (i1, j1) -> {
                if (b[i1] < b[j1]) return -1;
                if (b[i1] > b[j1]) return 1;
                return 0;
            });

            pos = 0;
            treap1 = null;
            treap2 = null;
            for (int i = 0; i < n; i++) {
                int ind = perm.get(i);
                while (pos < n && b[perm2.get(pos)] < a[ind]) {
                    // add to treap
                    int j = perm2.get(pos);
                    treap1 = Treap.insert(treap1, c[j], 1);
                    treap2 = Treap.insert(treap2, d[j], 1);
                    pos++;
                }
                int ALL = treap1 == null ? 0 : treap1.size;

                int l = c[ind], r = d[ind];
                // right end < l + left end > r
                if (Treap.query(treap1, r + 1, 1 << 30).sum + Treap.query(treap2, 0, l - 1).sum != ALL) {
                    out.println("NO");
                    return;
                }
            }

            out.println("YES");
        }

    }

    static class Treap {
        static Random random = new Random();

        public static Treap.TreapPair split(Treap.Node root, long minRight) {
            if (root == null)
                return new Treap.TreapPair(null, null);
            root.push();
            if (root.key >= minRight) {
                Treap.TreapPair sub = split(root.left, minRight);
                root.left = sub.right;
                root.pull();
                sub.right = root;
                return sub;
            } else {
                Treap.TreapPair sub = split(root.right, minRight);
                root.right = sub.left;
                root.pull();
                sub.left = root;
                return sub;
            }
        }

        public static Treap.Node merge(Treap.Node left, Treap.Node right) {
            if (left == null)
                return right;
            if (right == null)
                return left;
            left.push();
            right.push();
            if (left.prio > right.prio) {
                left.right = merge(left.right, right);
                left.pull();
                return left;
            } else {
                right.left = merge(left, right.left);
                right.pull();
                return right;
            }
        }

        public static Treap.Node insert(Treap.Node root, long key, long value) {
            Treap.TreapPair t = split(root, key);
            return merge(merge(t.left, new Treap.Node(key, value)), t.right);
        }

        public static Treap.TreapAndResult query(Treap.Node root, long ll, long rr) {
            Treap.TreapPair t1 = split(root, rr + 1);
            Treap.TreapPair t2 = split(t1.left, ll);
            long mx = Treap.Node.getMx(t2.right);
            long sum = Treap.Node.getSum(t2.right);
            return new Treap.TreapAndResult(merge(merge(t2.left, t2.right), t1.right), mx, sum);
        }

        public static class Node {
            long nodeValue;
            long mx;
            long sum;
            long add;
            long key;
            int size;
            long prio;
            Treap.Node left;
            Treap.Node right;

            Node(long key, long value) {
                this.key = key;
                nodeValue = value;
                mx = value;
                sum = value;
                add = 0;
                size = 1;
                prio = random.nextLong();
            }

            void apply(long v) {
                nodeValue += v;
                mx += v;
                sum += v * size;
                add += v;
            }

            void push() {
                if (add != 0) {
                    if (left != null)
                        left.apply(add);
                    if (right != null)
                        right.apply(add);
                    add = 0;
                }
            }

            void pull() {
                mx = Math.max(nodeValue, Math.max(getMx(left), getMx(right)));
                sum = nodeValue + getSum(left) + getSum(right);
                size = 1 + getSize(left) + getSize(right);
            }

            static long getMx(Treap.Node root) {
                return root == null ? Long.MIN_VALUE : root.mx;
            }

            static long getSum(Treap.Node root) {
                return root == null ? 0 : root.sum;
            }

            static int getSize(Treap.Node root) {
                return root == null ? 0 : root.size;
            }

        }

        public static class TreapPair {
            Treap.Node left;
            Treap.Node right;

            TreapPair(Treap.Node left, Treap.Node right) {
                this.left = left;
                this.right = right;
            }

        }

        public static class TreapAndResult {
            Treap.Node treap;
            long mx;
            long sum;

            TreapAndResult(Treap.Node t, long mx, long sum) {
                this.treap = t;
                this.mx = mx;
                this.sum = sum;
            }

        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int nextInt() {
            int c = read();
            while (isSpaceChar(c)) c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void println(Object... objects) {
            for (int i = 0; i < objects.length; i++) {
                if (i != 0) {
                    writer.print(' ');
                }
                writer.print(objects[i]);
            }
            writer.print('\n');
        }

        public void close() {
            writer.close();
        }

    }
}

