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 <bits/stdc++.h>
#define mp make_pair
#define mt make_tuple
#define X first
#define Y second
#define ALL(x) x.begin(),x.end()
#define RALL(x) x.rbegin(),x.rend()
#define D double
#define ll long long
#define REP(i,a) for(int i=0;i<a;i++)
#define REP1(i,a,b) for(int i=a;i<b;i++)
#define REP2(i,a,b) for(int i=a;i<=b;i++)
#define RREP(i,a) for(int i=a-1;i>=0;i--)
#define RREP1(i,a,b) for(int i=a;i>b;i--)
#define RREP2(i,a,b) for(int i=a;i>=b;i--)
#define SREP(i,x) for(auto i:x)
#define MS0(x) memset((x),0,sizeof((x)))
#define MS1(x) memset((x),-1,sizeof((x)))
#define MSF(x) memset((x),127,sizeof(x))
#define pb push_back
#define LE(x) (int)((x).size())
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define PDD pair<D,D>
#define im guagua
#define RI(x) x=rit()
#define RII(a,b) a=rit(),b=rit()
#define RIII(a,b,c) a=rit(),b=rit(),c=rit()
#define debug 0
const int INF = 0x7F7F7F7F;
const double EPS = 1e-10 ;
const ll mod7 = 1e9+7;
const ll mod9 = 1e9+9;
using namespace std;
inline ll rit(){
    ll f=0,key=1;
    char c;
    do{
        c=getchar();
        if(c=='-') key=-1;
    }while(c<'0' || c>'9');
    do{
        f=f*10+c-'0';
        c=getchar();
    }while(c>='0' && c<='9');
    return f*key;
}
inline void fprt(D f){
    printf("%.08lf",f);
}
void init(){
}
const int Z = 100005;
int r,c,n;
pair< PII , PII > p[Z];
int cnt[Z];
vector< pair<PII,int> > v;
int srt(pair<PII,int> a,pair<PII,int> b){
    if(a.X.X == 0 && b.X.X == 0){
        return a.X.Y < b.X.Y;
    }
    else if(a.X.X == 0) return 1;
    else if(b.X.X == 0) return 0;
    else{
        if(a.X.Y == c && b.X.Y == c){
            return a.X.X < b.X.X;
        }
        else if(a.X.Y == c) return 1;
        else if(b.X.Y == c) return 0;
        else{
            if(a.X.X == r && b.X.X == r){
                return a.X.Y  > b.X.Y;
            }
            else if(a.X.X == r) return 1;
            else if(b.X.X == r) return 0;
            else {
                if(a.X.Y == 0 && b.X.Y == 0){
                    return a.X.X > b.X.X;
                }
                else if(a.X.Y == 0 ) return 1;
                else if(b.X.Y == 0 ) return 0;
                else assert(0);
            }
        }
    } 
}
inline int onedge(PII p){
    if(p.X == 0 || p.X == r || p.Y == 0 || p.Y == c) return 1;
    return 0;
}
void read(){
    RIII(r,c,n);
    REP(i,n){
        RII(p[i].X.X,p[i].X.Y);
        RII(p[i].Y.X,p[i].Y.Y);
    }
}
stack<int> st;
void solve(){
    int m,now;
    REP(i,n){
        if(onedge(p[i].X) && onedge(p[i].Y)){
            v.pb(mp(p[i].X,i));
            v.pb(mp(p[i].Y,i));
        }
    }
    sort(ALL(v),srt);
    m = LE(v);
    // SREP(f,v){
    //     cout<<f.X.X<<' '<<f.X.Y<<" = "<<f.Y<<endl;
    // }
    REP(i,m){
        now = v[i].Y;
        if(cnt[now] == 0){
            cnt[now]++;
            st.push(now);
        }
        else{
            cnt[now]++;
            if(st.empty() || st.top() != now){
                cout<<"NO"<<endl;
                return ;
            }
            st.pop();
        }
        // if(v[(i-1+m)%m].Y != v[i].Y && v[(i+1)%m].Y != v[i].Y){
        //     cout<<"NO"<<endl;
        //     return ;
        // }
    }
    cout<<"YES"<<endl;
    return ;
}
int main(){
    int nn=1;
    // nn=rit();
    while(nn--){
        // while(cin>>n) 
            init(),read(),solve();
    }
    return 0;
}