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 Rust (1.15.1) (judge verdict: Accepted)

mod reader {
    use std::fmt::Debug;
    use std::str::FromStr;
    use std::collections::VecDeque;
    use std::io::{self, Read};

    fn _read_line() -> String {
        let mut buf = String::new();
        let _ = io::stdin().read_to_string(&mut buf);
        buf
    }

    fn _read_vec_deque_string() -> VecDeque<String> {
        _read_line()
            .split_whitespace()
            .map(|s| s.to_string())
            .collect()
    }

    pub struct Reader {
        buf: VecDeque<String>,
    }

    #[allow(dead_code)]
    impl Reader {
        pub fn new() -> Reader {
            Reader { buf: VecDeque::new() }
        }

        fn update_buf(&mut self) {
            if self.buf.is_empty() {
                self.buf = _read_vec_deque_string();
            }
        }

        pub fn next<T>(&mut self) -> T
        where
            T: FromStr,
            T::Err: Debug,
        {
            self.update_buf();
            self.buf.pop_front().unwrap().parse::<T>().unwrap()
        }

        pub fn next_n<T>(&mut self, n: usize) -> Vec<T>
        where
            T: FromStr,
            T::Err: Debug,
        {
            let mut vec: Vec<T> = Vec::with_capacity(n);

            for _ in 0..n {
                vec.push(self.next());
            }
            vec
        }
    }
}

fn inside(x: i32, y: i32, r: i32, c: i32) -> bool {
    x > 0 && x < c && y > 0 && y < r
}

fn f(x: i32, y: i32, r: i32, c: i32) -> i32 {
    if y > 0 && x < c {
        x + y
    } else {
        r + c + (r - y) + (c - x)
    }
}

fn main() {
    let mut reader = reader::Reader::new();

    let c = reader.next();
    let r = reader.next();
    let n: i32 = reader.next();

    let mut a: Vec<(i32, i32)> = Vec::new();

    for i in 1..n + 1 {
        let (x1, y1) = (reader.next(), reader.next());
        let (x2, y2) = (reader.next(), reader.next());
        if inside(x1, y1, r, c) || inside(x2, y2, r, c) {
            continue;
        }

        let x1 = f(x1, y1, r, c);
        let x2 = f(x2, y2, r, c);

        a.push((std::cmp::min(x1, x2), i));
        a.push((std::cmp::max(x1, x2), -i));
    }

    a.sort();
    let mut ng = false;
    use std::collections::VecDeque;
    let mut st: VecDeque<(i32, i32)> = VecDeque::new();
    for p in a {
        let i = p.1;
        // println!("{} {}", x, i);
        if i > 0 {
            st.push_back((p));
        } else {
            let i = -i;
            match st.pop_back() {
                Some(p2) => if p2.1 != i {ng = true; break;},
                None => {ng = true; break;},
            }
        }
    }
    println!("{}", if ng { "NO" } else { "YES" });
}