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: Accepted)



import java.io.FileNotFoundException;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
import java.util.Stack;

public class Main {
	public static void main(String[] args) throws FileNotFoundException {
		new Main().run();
	}

	class State {
		int id;
		int col;

		public State(int id_, int col_) {
			id = id_;
			col = col_;
		}
	}

	int R, C, N;

	void run() {
		Scanner sc = new Scanner(System.in);
		C = sc.nextInt();
		R = sc.nextInt();
		N = sc.nextInt();
		ArrayList<State> lis = new ArrayList<>();
		for (int i = 0; i < N; ++i) {
			boolean f = true;
			ArrayList<State> tmp = new ArrayList<>();
			for (int t = 0; t < 2; ++t) {
				int x = sc.nextInt();
				int y = sc.nextInt();
				f &= x == 0 || x == C || y == 0 || y == R;
				if (f)
					tmp.add(new State(edge_id(x, y), i));
			}
			if (f) {
				lis.addAll(tmp);
			}
		}
		Collections.sort(lis, new Comparator<State>() {
			@Override
			public int compare(State o1, State o2) {
				return Integer.compare(o1.id, o2.id);
			}
		});
		ArrayDeque<Integer> stk = new ArrayDeque<Integer>();
		int[] col = new int[N];
		for (int i = 0; i < lis.size(); ++i) {
			State s = lis.get(i);
			if (col[s.col] == 0) {
				stk.addLast(s.col);
				++col[s.col];
			} else {
				int pre = stk.pollLast();
				if (pre != s.col) {
					System.out.println("NO");
					return;
				}
				--col[s.col];
			}
		}
		System.out.println("YES");
	}

	int edge_id(int x, int y) {
		if (y == 0) {
			return x;
		} else if (x == C) {
			return C + y;
		} else if (y == R) {
			return C + R + C - x;
		} else if (x == 0) {
			return C + R + C + R - y;
		} else {
			tr(x, y, C, R);
			throw new AssertionError();
		}
	}

	void tr(Object... objects) {
		System.out.println(Arrays.deepToString(objects));
	}
}