#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
typedef long long ll;
#define N 200002
struct edge{int to,nxxt;}e[N<<1];
int n,H,a[N][4],head[N],cnt=1,b[N][2],f[N],rd[N],cd[N],ct[N];
vector<int>v[N];
inline void ins(int u,int v){e[cnt].to=v;e[cnt].nxxt=head[u];head[u]=cnt++;}
int getroot(int t){return f[t]==-1?t:f[t]=getroot(f[t]);}
int main()
{
    scanf("%d%d",&n,&H);
    memset(f,-1,sizeof(f));
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d%d%d",&a[i][0],&a[i][1],&a[i][2],&a[i][3]);
        int x,y;
        if(a[i][2]==0)x=a[i][0];else x=H+a[i][2];
        if(a[i][3]==0)y=H+a[i][1];else y=a[i][3];
        b[i][0]=x,b[i][1]=y;
        if(x==y)ct[x]++;
        ins(x,y),rd[y]++,cd[x]++;
        x=getroot(x);y=getroot(y);
        if(x^y)f[x]=y;
    }
    for(int i=1;i<=2*H;i++)v[getroot(i)].push_back(i);
    //for(int i=1;i<=2*H;i++)printf("%d ",getroot(i));puts("rt");
    //for(int i=1;i<=2*H;i++)printf("%d ",cd[i]);puts("cd");
    //for(int i=1;i<=2*H;i++)printf("%d ",rd[i]);puts("rd");
    for(int i=1;i<=2*H;i++)
    {
        bool flag=false;
        if(v[i].size()==1){if(ct[v[i][0]]){puts("NO");return 0;}}
        if(v[i].size()<=1)continue;
        //printf("%d:",i);
        for(int j=0;j<v[i].size();j++)
        {
            int x=v[i][j];
            if(rd[x]^cd[x]){flag=true;break;}
        }//puts("");
        if(!flag){puts("NO");return 0;}
    }
    bool flag=true;
    for(int i=1;i<=H;i++)
    {
        if(cd[i]<rd[i]){flag=false;break;}
    }
    for(int i=H+1;i<=2*H;i++)
    {
        if(rd[i]<cd[i]){flag=false;break;}
    }
    if(flag)puts("YES");else puts("NO");
}
/*
3 4
1 1 0 0
2 2 0 1
3 3 1 0
*/