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)

#![allow(unused_imports, unused_variables, dead_code)]
use std::io::*;
use std::fmt::*;
use std::str::*;
use std::cmp::*;
use std::collections::*;

trait InputValue {
    fn parse(s: &str) -> Self;
}

fn read<T: InputValue>() -> T {
    let mut buf = String::new();
    let _ = stdin().read_line(&mut buf);
    T::parse(&buf.trim())
}

fn readnc<T: InputValue>() -> Vec<T> {
    let mut vec = vec![];
    let line: String = read();
    for token in line.split_whitespace() {
        vec.push(T::parse(token));
    }
    vec
}

fn readn<T: InputValue>(n: usize) -> Vec<T> {
    let mut vec = vec![];
    for _ in 0..n {
        vec.push(read());
    }
    vec
}

macro_rules! parse_single_value {
    ($($t:ty),*) => {
        $(
            impl InputValue for $t {
                fn parse(s: &str) -> $t { s.parse().unwrap() }
            }
        )*
	}
}
parse_single_value!(i32, i64, f32, f64, usize, String);

macro_rules! parse_tuple {
	($($t:ident),*) => {
		impl<$($t),*> InputValue for ($($t),*) where $($t: InputValue),* {
			fn parse(s: &str) -> ($($t),*) {
				let mut tokens = s.split_whitespace();
				let t = ($($t::parse(tokens.next().unwrap())),*);
				t
			}
		}
	}
}
parse_tuple!(A, B);
parse_tuple!(A, B, C);
parse_tuple!(A, B, C, D);

// ===

const INF: usize = 1000000000;

fn decode(x: usize, y: usize, r: usize, c: usize) -> usize {
    if y == 0 {
        x
    } else if x == r {
        r + y
    } else if y == c {
        r + c + r - x
    } else if x == 0 {
        r + c + r + c - y
    }  else {
        INF
    }
}

fn main() {
    let (r, c, n): (usize, usize, usize) = read();
    let points: Vec<(usize, usize, usize, usize)> = readn(n);

    let mut pairs = vec![];
    for i in 0..n {
        let fpos = decode(points[i].0, points[i].1, r, c);
        let tpos = decode(points[i].2, points[i].3, r, c);
        if fpos == INF || tpos == INF {
            continue
        }
        pairs.push((fpos, i));
        pairs.push((tpos, i));
    }

    pairs.sort();

    let mut stk = VecDeque::new();
    let mut isok = true;
    let mut seen = vec![false; n];
    for i in 0..pairs.len() {
        let (_, i) = pairs[i];
        if !seen[i] {
            stk.push_front(i);
            seen[i] = true;
        } else {
            if stk.len() == 0 {
                isok = false;
                break
            }
            let last = stk.pop_front().unwrap();
            if last != i {
                isok = false;
                break
            }
        }
    }
    if stk.len() != 0 {
        isok = false;
    }

    if isok {
        println!("YES");
    } else {
        println!("NO");
    }
}