令一個點的權值為其到根的經過的邊的異或和
注意到可以將操作視為交換兩個點的權值
#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;
}