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 C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;

typedef struct V{
	int x1, y1, x2, y2;
}V;

int R, C;
int get_num(int x, int y) {
	if(y==C && x<R) return 1;
	else if(x==R && y>0) return 2;
	else if(y==0 && x>0) return 3;
	else if(x==0 && y<C) return 4;
	return -1;
}
/*
		1
	----------
	|        |
  4 |        | 2
	|        |
	----------
		3

mys[1]: 1, 2
mys[2]: 1, 3
mys[3]: 1, 4
...
mys[6]: 3, 4
*/
vector<V> mys[7];

bool is_in(int x, int l, int r) {
	if(l<=x && x<=r) return true;
	return false;
}

int main() {
	scanf("%d %d", &R, &C);

	int n;
	scanf("%d", &n);
	for(int i=0;i<n;i++) {
		int x1, y1, x2, y2;
		scanf("%d %d %d %d", &x1, &y1, &x2, &y2);

		if(y1==0 && y2==0) continue;
		if(y1==C && y2==C) continue;
		if(x1==0 && x2==0) continue;
		if(x1==R && x2==R) continue;

		int num1 = get_num(x1, y1);
		int num2 = get_num(x2, y2);
		if(num1==-1 || num2==-1) continue;
		if(num1==num2) continue;

		if(num1>num2) {
			swap(num1, num2);
			swap(x1, x2);
			swap(y1, y2);
		}
		V cur = {x1, y1, x2, y2};
		if(num1==1 && num2==2)
			mys[1].push_back(cur);
		else if(num1==1 && num2==3) {
			mys[2].push_back(cur);
		}
		else if(num1==1 && num2==4) {
			mys[3].push_back(cur);
		}
		else if(num1==2 && num2==3) {
			mys[4].push_back(cur);
		}
		else if(num1==2 && num2==4) {
			mys[5].push_back(cur);
		}
		else
			mys[6].push_back(cur);
	}

	if(mys[2].size() && mys[5].size()) {
		puts("NO");
		return 0;
	}

	// for(int i=1;i<=6;i++)
	// 	printf("mys[%d].size=%d\n", i, mys[i].size());

	bool inv = false;

	vector<V> cand;
	// 1, 2
	int x = R, y = C;
	for(auto nxt: mys[1]) {
		int cx = nxt.x1;
		int cy = nxt.y2;

		if(cx>x || cy>y) {
			inv = true;
			break;
		}
		x = min(x, cx);
		y = min(y, cy);
	}
	cand.push_back({x, C, R, y});
	if(inv){
		puts("NO");
		return 0;
	}

	// 2, 3
	x = R, y = 0;
	for(auto nxt: mys[4]) {
		int cx = nxt.x2, cy = nxt.y1;
		if(cx>x || cy<y) {
			inv = true;
			break;
		}
		x = min(x, cx);
		y = max(y, cy);
	}
	cand.push_back({R, y, x, C});
	if(inv) {
		puts("NO");
		return 0;
	}

	// 3, 4
	x = 0, y = 0;
	for(auto nxt: mys[6]) {
		int cx = nxt.x1, cy = nxt.y2;
		if(cx<x || cy<y) {
			inv = true;
			break;
		}
		x = max(x, cx);
		y = max(y, cy);
	}
	cand.push_back({x, 0, 0, y});
	if(inv) {
		puts("NO");
		return 0;
	}

	// 1, 4
	x = 0, y = C;
	for(auto nxt: mys[3]) {
		int cx = nxt.x1, cy = nxt.y2;
		if(cx<x || cy>y) {
			inv = true;
			break;
		}
		x = max(x, cx);
		y = min(y, cy);
	}
	cand.push_back({x, C, 0, y});
	if(inv) {
		puts("NO");
		return 0;
	}

	if(cand[0].y2<cand[1].y1) {
		inv = true;
	}
	if(cand[1].x2<cand[2].x1) {
		inv = true;
	}
	if(cand[2].y2>cand[3].y2) {
		inv = true;
	}
	if(cand[3].x1>cand[0].x1) {
		inv = true;
	}
	if(inv) {
		puts("NO");
		return 0;
	}

	if(mys[2].size()) {
		int xtl = cand[3].x1;
		int xtr = cand[0].x1;
		int xbl = cand[2].x1;
		int xbr = cand[1].x2;

		// printf("[%d, %d], [%d, %d]\n", xtl, xtr, xbl, xbr);

		int xtm1=-1, xtm2=-1;
		int xbm1=-1, xbm2=-1;
		for(auto nxt: mys[2]) {
			int cxt = nxt.x1;
			int cxb = nxt.x2;

			if(!is_in(cxt, xtl, xtr) || !is_in(cxb, xbl, xbr)) {
				inv = true;
				break;
			}

			if(xtm1==-1) {
				xtm1 = xtm2 = cxt;
				xbm1 = xbm2 = cxb;
			}
			else {
				if(!is_in(cxt, xtl, xtm1) || !is_in(cxt, xtm2, xtr)) {
					inv = true;
					break;
				}

				if(!is_in(cxb, xbl, xbm1) || !is_in(cxb, xbm2, xbr)) {
					inv = true;
					break;
				}

				if(is_in(cxt, xtl, xtm1))
					xtm1 = cxt;
				else
					xtm2 = cxt;

				if(is_in(cxb, xbl, xbm1))
					xbm1 = cxb;
				else
					xbm2 = cxb;
			}
		}
	}
	else if(mys[5].size()) {
		int xtr = cand[0].y2;
		int xtl = cand[1].y1;

		int xbr = cand[3].y2;
		int xbl = cand[2].y2;

		// printf("[%d, %d], [%d, %d]\n", xtl, xtr, xbl, xbr);

		int xtm1=-1, xtm2=-1;
		int xbm1=-1, xbm2=-1;
		for(auto nxt: mys[5]) {
			int cxt = nxt.y1;
			int cxb = nxt.y2;
			// printf("%d %d\n", cxt, cxb);
			if(!is_in(cxt, xtl, xtr) || !is_in(cxb, xbl, xbr)) {
				inv = true;
				break;
			}

			if(xtm1==-1) {
				xtm1 = xtm2 = cxt;
				xbm1 = xbm2 = cxb;
			}
			else {
				if(!is_in(cxt, xtl, xtm1) || !is_in(cxt, xtm2, xtr)) {
					inv = true;
					break;
				}

				if(!is_in(cxb, xbl, xbm1) || !is_in(cxb, xbm2, xbr)) {
					inv = true;
					break;
				}

				if(is_in(cxt, xtl, xtm1))
					xtm1 = cxt;
				else
					xtm2 = cxt;

				if(is_in(cxb, xbl, xbm1))
					xbm1 = cxb;
				else
					xbm2 = cxb;
			}
		}
	}

	if(inv) {
		puts("NO");
		return 0;
	}

	puts("YES");
	return 0;
}