#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn = 2100; struct node{ int v,next; }edge[maxn*maxn]; int head[maxn],res[1005*1005][2],low[maxn],dfn[maxn],stack[maxn],in[maxn]; int n,m,id,clock,top; void add_edge(int u,int v){ edge[id].v = v;edge[id].next = head[u];head[u] = id++; } void init(){ int c1,c2; scanf("%d",&m); id = 0;memset(head,-1,sizeof(head)); for( int i = 0; i < m; i++){ scanf("%d%d%d%d",&res[i][0],&res[i][1],&c1,&c2); res[i][0] = res[i][0]*2 + c1; res[i][1] = res[i][1]*2 + c2; //两个方向必须相反,否则求出的结果会不对 add_edge(res[i][0],res[i][1]^1); add_edge(res[i][1],res[i][0]^1); } } void tarjan(int u){ low[u] = dfn[u] = ++clock; stack[top++] = u; in[u] = 1; for(int id = head[u]; id != -1 ; id = edge[id].next){ int v = edge[id].v; if( !dfn[v] ){ tarjan(v); low[u] = low[u] < low[v] ? low[u] : low[v]; } else if( in[v] && low[u] > dfn[v]) low[u] = dfn[v]; } if( low[u] == dfn[u]){ do{ in[stack[--top]] = 0; }while( u != stack[top]); } } int main(){ //freopen("in.txt","r",stdin); int i; while( ~scanf("%d",&n)){ init(); memset(dfn,0,sizeof(dfn)); memset(in,0,sizeof(0)); clock = top = 0; for( i = 0; i < n*2 ; i++) if( !dfn[i]) tarjan(i); for( i = 0; i < m; i++)//在同一个强连通分量中的low值相等 if(low[res[i][0]] == low[res[i][1]]) break; if( i < m )puts("NO"); else puts("YES"); } return 0; }