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


#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
//#include <regex>

/* g++ -g -std=c++0x */
/* g++ -g -std=c++11 */

using namespace std;

// std::ios::sync_with_stdio(false);

// freopen("input.txt", "rt", stdin);
// freopen("output.txt", "wt", stdout);

#define ALL(c)          (c).begin(), (c).end()
#define ALLR(c)         (c).rbegin(), (c).rend()
#define FOR(i,a,b)      for (int i=(a); i < (b); ++i)
#define FORR(i,a,b)     for (int i=(a); i > (b); --i)
#define FOR_ALL(i,c)    for (__typeof((c).begin()) i=(c).begin();   \
                             i != (c).end(); ++i)
#define FOR_ALLR(i,c)   for (__typeof((c).rbegin()) i=(c).rbegin(); \
                             i != (c).rend(); ++i)
#define SZ(array)       (sizeof(array)/sizeof(array[0]))
#define lc(x)           (x<<1)     /* 2*x */
#define rc(x)           (x<<1 | 1) /* 2*x+1 */
#define lowbit(x)       (x & (-x)) /* 0b10100 -> 0b100 */

typedef long long       LL;
typedef map<int,int>    MII;
typedef pair<int,int>   PII;
typedef set<int>        SI;
typedef vector<bool>    VB;
typedef vector<double>  VD;
typedef vector<int>     VI;
typedef vector<string>  VS;

/* check if a key is in container C */
template <class C>
inline bool in_(const typename C::key_type& k, const C& A)
{ return A.find(k) != A.end(); }
inline bool in_(const string& s, const string& S)
{ return S.find(s) != string::npos; }

/*
 * We call an integer "important", if both occurrences of this integer
 * is on the boundary of the rectangle.
 *
 * Suppose that there are two important integers i and j, and they
 * appear in the boundary in the order i,j,i,j. In this case, it is
 * clear that we can't connect both integers without crossing.
 * Otherwise, we can connect all integers in the following order:
 *
 * First, we connect non-important integers one by one.
 * Then, we connect important integers one by one.
 *
 * This way, we never get stuck.
 *
 * => the curve line can be very very thin, so there is always room to
 * => draw inside the rectangle.
 *
 * How can we check if there exists such a pair (i,j) of important
 * integers? Start from an arbitrary point on the boundary and check all
 * important points on the boundary one by one in clockwise order
 * (ignore non-important integers on the boundary). Initially we have an
 * empty stack, and whenever we find an important integer x on the
 * boundary, do the following:
 *
 * If the top element of the stack is also x, pop it.
 * Otherwise, push x into the stack.
 *
 * If the stack becomes empty after we check all points, the answer is
 * "Yes". Otherwise the answer is "No".
 */

typedef pair<int,int> Point;
map<Point,int> id;
int R,C,N;

bool cmp(const Point& a, const Point& b)
{
    const int x1 = a.first, y1 = a.second;
    const int x2 = b.first, y2 = b.second;
    bool ans = false;
    if (x1 == 0)                /* a is at top */
        ans = !(x2 == 0 && y2 < y1);
    else if (y1 == C)           /* a is at right side */
        ans = !(x2 == 0 || (x2 < x1 && y2 == C));
    else if (x1 == R)           /* a is at bottom */
        ans = !(x2 == 0 || y2 > y1);
    else                        /* a is at left side */
        ans = !(x2 == 0 || y2 > y1 || x2 > x1);
    return ans;
}

bool onboarder(const  Point& p)
{
    const int x = p.first;
    const int y = p.second;
    return x == 0 || x == R || y == 0 || y == C;
}

int main()
{
/* #ifndef ONLINE_JUDGE */
/*     freopen("foo", "rt", stdin); */
/* #endif */
    while (cin >> R >> C >> N) {
        id.clear(); int cnt = 1; vector<Point> V;
        FOR(_,0,N) {
            Point p1,p2;
            cin >> p1.first >> p1.second >> p2.first >> p2.second;
            if (onboarder(p1) && onboarder(p2)) {
                V.push_back(p1), V.push_back(p2);
                id[p1] = id[p2] = cnt++;
            }
        }
        sort(ALL(V),cmp);
        stack<int> S;
        FOR_ALL(p,V) {
            if (S.size() && S.top() == id[*p])
                S.pop();
            else
                S.push(id[*p]);
        }
        const string ans = S.empty() ? "YES" : "NO";
        cout << ans << endl;
    }
    return 0;
}