#include <algorithm>  
#include <iostream>  
#include <sstream>  
#include <string>  
#include <cstring>
#include <vector>  
#include <queue>  
#include <set>  
#include <map>  
#include <cstdio>  
#include <cstdlib>  
#include <cctype>  
#include <cmath>  
#include <list>  
#include <cassert>
#include <ctime>
#include <climits>
using namespace std;  

#define PB push_back  
#define MP make_pair  
#define SZ(v) ((int)(v).size())  
#define FOR(i,a,b) for(int i=(a);i<(b);++i)  
#define REP(i,n) FOR(i,0,n)  
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)  
#define REPE(i,n) FORE(i,0,n)  
#define FORSZ(i,a,v) FOR(i,a,SZ(v))  
#define REPSZ(i,v) REP(i,SZ(v))  
typedef long long ll;
typedef unsigned long long ull;
ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); }

const int MAXN=100000;
const int MAXH=200;
typedef struct Z { int A,B,C,D,L,R; vector<int> mid; } Z;

int n,h;
Z z[2*MAXN];
bool used[2*MAXN];


vector<int> havel[2*MAXH];
vector<int> haver[2*MAXH];
vector<int> havec[2*MAXH];
int cnt[2*MAXH];

bool solve() {
	REP(i,n) { if(z[i].C==0) z[i].L=z[i].A-1; else z[i].L=h+z[i].C-1; if(z[i].D==0) z[i].R=h+z[i].B-1; else z[i].R=z[i].D-1; }
	//REP(i,n) { if(i!=0) printf(" | "); printf("%02d-%02d",z[i].L,z[i].R); } puts("");
	REP(i,2*h) havel[i].clear(),haver[i].clear(); REP(i,n) havel[z[i].L].PB(i),haver[z[i].R].PB(i),used[i]=false;

	bool ret=true; int nz=n;
	REP(i,n) if(!used[i]) {
		used[i]=true;
		int l=z[i].L,r=z[i].R; REP(j,2*h) cnt[j]=0;
		//printf("%02d-%02d\n",l,r);
		while(true) {
			bool change=false;
			while(true) {
				while(SZ(havel[r])!=0&&used[havel[r].back()]) havel[r].pop_back();
				if(SZ(havel[r])!=0) { int id=havel[r].back(); used[id]=true; ++cnt[r]; r=z[id].R; change=true; /*printf("append right %02d-%02d\n",z[id].L,z[id].R);*/ } else break;
			}
			while(true) {
				while(SZ(haver[l])!=0&&used[haver[l].back()]) haver[l].pop_back();
				if(SZ(haver[l])!=0) { int id=haver[l].back(); used[id]=true; ++cnt[l]; l=z[id].L; change=true; /*printf("append left  %02d-%02d\n",z[id].L,z[id].R);*/ } else break;
			}
			if(!change&&l==r) REP(j,2*h) if(cnt[j]>0||j==l) {
				while(SZ(havel[j])!=0&&used[havel[j].back()]) havel[j].pop_back();
				while(SZ(haver[j])!=0&&used[haver[j].back()]) haver[j].pop_back();
				while(SZ(havec[j])!=0&&used[havec[j].back()]) havec[j].pop_back();
				if(SZ(havel[j])!=0) { int id=havel[j].back(); used[id]=true; ++cnt[l]; l=j,r=z[id].R; change=true; /*printf("split on %02d and append right %02d-%02d\n",j,z[id].L,z[id].R);*/ break; }
				if(SZ(haver[j])!=0) { int id=haver[j].back(); used[id]=true; ++cnt[l]; l=z[id].L,r=j; change=true; /*printf("split on %02d and append left  %02d-%02d\n",j,z[id].L,z[id].R);*/ break; }
				if(SZ(havec[j])!=0) { int id=havec[j].back(); used[id]=true; ++cnt[l]; l=z[id].L,r=z[id].R; change=true; REPSZ(k,z[id].mid) ++cnt[z[id].mid[k]]; /*printf("split on %02d and append in middle %02d-%02d\n",j,z[id].L,z[id].R);*/ break; }
			}
			if(!change) break;
		}
		//printf("-> %02d-%02d:",l,r); REP(j,2*h) if(cnt[j]>0) printf(" %02d",j); puts("");
		if(l>=h||r<h) ret=false; else { z[nz].L=l,z[nz].R=r,used[nz]=false; REP(j,2*h) if(cnt[j]>0) z[nz].mid.PB(j),havec[j].PB(nz); ++nz; }
	}
	return ret;
}


void run() {
	scanf("%d%d",&n,&h);
	REP(i,n) scanf("%d%d%d%d",&z[i].A,&z[i].B,&z[i].C,&z[i].D);
	//REP(i,n) { if(i!=0) printf(" | "); if(z[i].C==0) printf("0%d",z[i].A); else printf("%d*",z[i].C); printf("-"); if(z[i].D==0) printf("0%d",z[i].B); else printf("%d*",z[i].D); } puts("");
	printf("%s\n",solve()?"YES":"NO");	
}

int main() {
	run();
	return 0;
}


Measured memory_bytes: 11904