Problem:
Score : 1000 points

Problem Statement

You are given a tree with N vertices. The vertices are numbered 0 through N-1, and the edges are numbered 1 through N-1.
Edge i connects Vertex x_i and y_i, and has a value a_i.
You can perform the following operation any number of times:

Choose a simple path and a non-negative integer x, then for each edge e that belongs to the path, change a_e by executing a_e ← a_e ⊕ x (⊕ denotes XOR).

Your objective is to have a_e = 0 for all edges e.
Find the minimum number of operations required to achieve it.

Constraints

2 ≤ N ≤ 10^5

0 ≤ x_i,y_i ≤ N-1

0 ≤ a_i ≤ 15

The given graph is a tree.

All input values are integers.

Input

Input is given from Standard Input in the following format:

N
x_1 y_1 a_1
x_2 y_2 a_2
:
x_{N-1} y_{N-1} a_{N-1}

Output

Find the minimum number of operations required to achieve the objective.

Sample Input 1

5
0 1 1
0 2 3
0 3 6
3 4 4

Sample Output 1

3

The objective can be achieved in three operations, as follows:

First, choose the path connecting Vertex 1, 2, and x = 1.

Then, choose the path connecting Vertex 2, 3, and x = 2.

Lastly, choose the path connecting Vertex 0, 4, and x = 4.

Sample Input 2

2
1 0 0

Sample Output 2

0

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#define ll long long
#define maxn 200005
#define re register
#define inf 1e9
#define eps 1e-10
using namespace std;

inline int read()
{
	int x=0,w=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
	while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
	return w==1?x:-x;
}

int a[maxn],cnt[16],ans;
int b[16],cnt1,sz[maxn],sz2[maxn],dp[maxn];

inline int gs(int sta)
{
	for(int i=1;i<=cnt1;i++) if((sta&(1<<(i-1)))) sz[sta]^=b[i];
}

int main()
{
	int n=read();
	for(int i=1;i<n;i++)
	{
		int u=read(),v=read(),w=read();
		a[u]^=w; a[v]^=w;
	}
	for(int i=0;i<n;i++)
	{
		if(a[i]==0) continue;
		if(cnt[a[i]]) cnt[a[i]]=0,ans++;
		else cnt[a[i]]=1;
	}
	for(int i=1;i<=15;i++) if(cnt[i]) b[++cnt1]=i;
	int ed=(1<<cnt1)-1;
	//for(int i=1;i<=cnt1;i++) cout<<b[i]<<" "; cout<<endl;
	for(int i=1;i<=ed;i++) gs(i),sz2[i]=sz2[i>>1]+(i&1);
	for(int i=1;i<=ed;i++) dp[i]=sz2[i]-1;
	//for(int i=0;i<=ed;i++) cout<<i<<" "<<sz[i]<<" "<<sz2[i]<<endl;
	for(int i=1;i<=ed;i++)
	{
		if(sz[i]!=0) continue;
		for(int j=i;j;j=(j-1)&i)
		{
			if(sz[j]==0) dp[i]=min(dp[i],dp[j]+dp[i^j]);
			//else dp[i]=min(dp[i],sz2[j]+sz2[i^j]+1);
		}
	}
	cout<<dp[ed]+ans<<endl;
	//for(int i=0;i<=ed;i++) cout<<i<<" "<<dp[i]<<endl;
	return 0;
}