Problem:
Score : 700 points

Problem Statement

Snuke is playing a puzzle game.
In this game, you are given a rectangular board of dimensions R × C, filled with numbers. Each integer i from 1 through N is written twice, at the coordinates (x_{i,1},y_{i,1}) and (x_{i,2},y_{i,2}).

The objective is to draw a curve connecting the pair of points where the same integer is written, for every integer from 1 through N.
Here, the curves may not go outside the board or cross each other.

Determine whether this is possible.

Constraints

1 ≤ R,C ≤ 10^8

1 ≤ N ≤ 10^5

0 ≤ x_{i,1},x_{i,2} ≤ R(1 ≤ i ≤ N)

0 ≤ y_{i,1},y_{i,2} ≤ C(1 ≤ i ≤ N)

All given points are distinct.

All input values are integers.

Input

Input is given from Standard Input in the following format:

R C N
x_{1,1} y_{1,1} x_{1,2} y_{1,2}
:
x_{N,1} y_{N,1} x_{N,2} y_{N,2}

Output

Print YES if the objective is achievable; print NO otherwise.

Sample Input 1

4 2 3
0 1 3 1
1 1 4 1
2 0 2 2

Sample Output 1

YES

The above figure shows a possible solution.

Sample Input 2

2 2 4
0 0 2 2
2 0 0 1
0 2 1 2
1 1 2 1

Sample Output 2

NO

Sample Input 3

5 5 7
0 0 2 4
2 3 4 5
3 5 5 2
5 5 5 4
0 3 5 1
2 2 4 4
0 5 4 1

Sample Output 3

YES

Sample Input 4

1 1 2
0 0 1 1
1 0 0 1

Sample Output 4

NO

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Wrong Answer)

import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;


public class Main {
    public static void main(String[] args) {
        FastScanner fsc = new FastScanner();
        long r = fsc.nextLong();
        long c = fsc.nextLong();
        int n = fsc.nextInt();
        HashSet<Line> edg = new HashSet<>();
        for (int i = 0; i < n; i++) {
            long x1 = fsc.nextLong();
            long y1 = fsc.nextLong();
            long x2 = fsc.nextLong();
            long y2 = fsc.nextLong();
            boolean e1 = x1 == 0 || x1 == r || y1 == 0 || y1 == c;
            boolean e2 = x2 == 0 || x2 == r || y2 == 0 || y2 == c;
            if (e1 && e2) {
                edg.add(new Line(x1, y1, x2, y2));
            }
        }
        System.out.println(crs(edg) ? "NO" : "YES");
    }

    public static boolean crs(HashSet<Line> set) {
        if (set.isEmpty()) {
            return false;
        }
        Iterator<Line> iter = set.iterator();
        Line l = iter.next();
        iter.remove();
        HashSet<Line> pos = new HashSet<>();
        while (iter.hasNext()) {
            Line t = iter.next();
            int c = l.cross(t);
            if (c == 0) {
                return true;
            } else if (c > 0) {
                pos.add(t);
                iter.remove();
            }
        }
        return crs(set) || crs(pos);
    }

    static class Line {
        public Complex c1, c2;

        public Line(long x1, long y1, long x2, long y2) {
            this.c1 = new Complex(x1, y1);
            this.c2 = new Complex(x2, y2);
        }

        public int cross(Line l) {
            Complex o = c1;
            Complex u = c2.sub(o);
            Complex v1 = l.c1.sub(o);
            Complex v2 = l.c2.sub(o);
            long opz12 = u.x * v1.y - u.y * v1.x;
            long opz13 = u.x * v2.y - u.y * v2.x;
            if (opz12 == 0 || opz13 == 0) {
                return 0;
            }
            if (opz12 > 0 ^ opz13 > 0) {
                return 0;
            } else if (opz12 > 0 && opz13 > 0) {
                return 1;
            } else {
                return -1;
            }
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            } else if (!(o instanceof Line)) {
                return false;
            } else {
                Line l = (Line) o;
                return this.c1.equals(l.c1) && this.c2.equals(l.c2);
            }
        }

        @Override
        public int hashCode() {
            return Objects.hash(c1, c2);
        }
    }
}


class FastScanner {
    private final InputStream in = System.in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;
    private boolean hasNextByte() {
        if (ptr < buflen) {
            return true;
        }else{
            ptr = 0;
            try {
                buflen = in.read(buffer);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (buflen <= 0) {
                return false;
            }
        }
        return true;
    }
    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
    private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
    public boolean hasNext() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++; return hasNextByte();}
    public String next() {
        if (!hasNext()) throw new NoSuchElementException();
        StringBuilder sb = new StringBuilder();
        int b = readByte();
        while(isPrintableChar(b)) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }
    public long nextLong() {
        if (!hasNext()) throw new NoSuchElementException();
        long n = 0;
        boolean minus = false;
        int b = readByte();
        if (b == '-') {
            minus = true;
            b = readByte();
        }
        if (b < '0' || '9' < b) {
            throw new NumberFormatException();
        }
        while(true){
            if ('0' <= b && b <= '9') {
                n *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return minus ? -n : n;
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
    public int nextInt() {
        long nl = nextLong();
        if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE) throw new NumberFormatException();
        return (int) nl;
    }
    public double nextDouble() { return Double.parseDouble(next());}
}


class Complex {
    public long x;
    public long y;

    public Complex(long x, long y) {
        this.x = x;
        this.y = y;
    }

    public Complex sub(Complex c) {
        return new Complex(x - c.x, y - c.y);
    }

    @Override
    public boolean equals(Object o) {
        if (o == this) {
            return true;
        } else if (o instanceof Complex) {
            Complex c = (Complex) o;
            return c.x == this.x && c.y == this.y;
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return Objects.hash(x, y);
    }
}