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 (Clang 3.8.0) (judge verdict: Runtime Error)

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

// c++11
#include <array>
#include <tuple>
#include <unordered_map>
#include <unordered_set>

#define mp make_pair
#define mt make_tuple
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;

const int INF = 1 << 29;
const ll LL_INF = 1LL << 60;
const double EPS = 1e-9;
const ll MOD = 1000000007;

const int dx[] = {1, 0, -1, 0}, dy[] = {0, -1, 0, 1};
struct Line
{
    Line() {}
    Line(int x1, int y1, int x2, int y2) : x1(x1), y1(y1), x2(x2), y2(y2)
    {
    }
    int x1, y1, x2, y2;
};

bool is_cross_x(int R, int x1, int x2)
{
    if (x1 == 0 and x2 == R)
    {
        return true;
    }
    if (x1 == R and x2 == 0)
    {
        return true;
    }
    return false;
}

bool is_cross_y(int C, int y1, int y2)
{
    if (y1 == 0 and y2 == C)
    {
        return true;
    }
    if (y1 == C and y2 == 0)
    {
        return true;
    }
    return false;
}

bool is_cross(int R, int C, vector<Line> &lines)
{
    const int N = lines.size();
    int cross_x, cross_y;
    cross_x = cross_y = 0;
    set<int> indices;
    for (int i = 0; i < N; i++)
    {
        if (is_cross_x(R, lines[i].x1, lines[i].x2))
        {
            cross_x++;
            indices.emplace(i);
        }
        if (is_cross_y(C, lines[i].y1, lines[i].y2))
        {
            cross_y++;
            indices.emplace(i);
        }
    }
    if (indices.size() > 1 and cross_x > 0 and cross_y > 0)
    {
        return true;
    }

    return false;
}

bool solve(int R, int C, vector<Line> &lines)
{
    if (is_cross(R, C, lines))
    {
        return false;
    }

    return true;
}

bool solve1(int R, int C, vector<Line> &lines)
{
    const int N = lines.size();
    vector<Line> candidates;
    for (int i = 0; i < N; i++)
    {
        if (is_cross_x(R, lines[i].x1, lines[i].x2))
        {
            candidates.emplace_back(lines[i]);
        }
    }
    sort(candidates.begin(), candidates.end(), [](const Line &left, const Line &right) {
        if (left.y1 < right.y1)
        {
            return true;
        }
        if (left.y2 <= right.y2)
        {
            return true;
        }
        return false;
    });
    int max_y = 0;
    for (int i = 0; i < candidates.size(); i++)
    {
        int y = candidates[i].y2;
        // cerr << candidates[i].x1 << " " << candidates[i].y1 << " " << candidates[i].x2 << " " << candidates[i].y2 << endl;
        if (y < max_y)
        {
            return false;
        }
        max_y = max(max_y, y);
    }
    return true;
}

int main()
{
    int R, C, N;
    cin >> R >> C >> N;
    vector<Line> lines;
    vector<Line> lines_inv;
    for (int i = 0; i < N; i++)
    {
        int x1, y1, x2, y2;
        cin >> x1 >> y1 >> x2 >> y2;
        if (x1 > x2)
        {
            swap(x1, x2);
            swap(y1, y2);
        }
        lines.emplace_back(Line(x1, y1, x2, y2));
        if (y1 > y2)
        {
            swap(x1, x2);
            swap(y1, y2);
        }
        lines_inv.emplace_back(Line(y1, x1, y2, x2));
    }
    bool ok = true;
    ok &= solve(R, C, lines);
    ok &= solve(C, R, lines_inv);
    ok &= solve1(R, C, lines);
    ok &= solve1(C, R, lines_inv);
    if (!ok)
    {
        cout << "NO" << endl;
        return 0;
    }
    // assert(false);
    cout << "YES" << endl;
    return 0;
}