令一个点的权值为其到根的经过的边的异或和
注意到可以将操作视为交换两个点的权值
#include<bits/stdc++.h>
using namespace std;
#define i128 __int128
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
#define fi first
#define se second
#define lowbit(x) ((x)&(-x))
#define It set<int>::iterator
//#define ls (rt<<1)
//#define rs (rt<<1|1)
//#define mid (l+r>>1)
//#define lson tr[rt].ls
//#define rson tr[rt].rs
//#define ls1 tr[rt1].ls
//#define rs1 tr[rt1].rs
//#define ls2 tr[rt2].ls
//#define rs2 tr[rt2].rs
#define pb emplace_back
const int mod=998244353;
int ksm(int x,int y){int res=1;while(y){if(y&1)res=1LL*res*x%mod;x=1LL*x*x%mod;y>>=1;}return res;
}
int n,f[100005],g[100005];
struct edge{int v,w1,w2,nx;
}e[200005];
int cnt,hd[100005];
void add(int u,int v,int w1,int w2){e[++cnt]=edge{v,w1,w2,hd[u]};hd[u]=cnt;
}
void dfs(int u,int fa){for(int i=hd[u];i;i=e[i].nx){int v=e[i].v;if(v==fa)continue;f[v]=f[u]^e[i].w1;g[v]=g[u]^e[i].w2;dfs(v,u);}
}
int main(){scanf("%d",&n);for(int i=1;i<n;i++){int u,v,w1,w2;scanf("%d%d%d%d",&u,&v,&w1,&w2);add(u,v,w1,w2);add(v,u,w1,w2);}dfs(1,0);int w=0;for(int i=1;i<=n;i++)w^=f[i]^g[i];for(int i=1;i<=n;i++)f[i]^=w;sort(f+1,f+1+n);sort(g+1,g+1+n);for(int i=1;i<=n;i++)if(f[i]!=g[i])puts("NO"),exit(0);puts("YES");return 0;
}