//最长异或路径,重点在于01tried树与异或的性质,首先因为异或的性质重复两次异或等于没有 操作也就没有 重复路径的
//顾虑
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define LL unsigned long long
using namespace std;
const int N = 2e6 + 10;
int head[N];
struct trie {
int ch[2];
}t[N];
struct edge {
int to;
int w;
int nxt;
}e[N];
int cnt = -1, sum[N];
inline void add(int u, int v, int w) {//建图
e[++cnt].to = v;
e[cnt].w = w;
e[cnt].nxt = head[u];
head[u] = cnt;
}
inline void dfs(int u, int fa) {//求到根路径的异或和
int v, w;
for (int i = head[u]; ~i; i = e[i].nxt) {
v = e[i].to;
w = e[i].w;
if (v != fa) {
sum[v] = sum[u] ^ w;
dfs(v, u);
}
}
}
int tot = 0;
inline void build(int n) {
for (int i = 1; i <= n; i++) {
bool k;
for (int j = (1 << 30), p = 0; j; j >>= 1) {
k = j & sum[i];
if (!t[p].ch[k]) {
t[p].ch[k] = ++tot;
}
p = t[p].ch[k];
}
}
}
int check(int val, int x) {
int ans = 0;
bool k;
for (int i = (1 << 30); i; i >>= 1) {
k = val & i;//计算该位的01,
if (t[x].ch[!k]) {//查看所有节点异或和值中在该路线的该位置有没有有值的,并且是不同于val的,这样异或值得该位便是1
//这里求出的答案中将所有sum的每一位01都铺成一条条01路径,通过对路径的选择最终选择出到底是那一条路径的01值,
//即哪一个sum,但是从val出发的求出的另一个sum仅仅代表从该val所代表的节点出发所能达到的最大的,因此要
//将所有节点都当做起点尝试一遍,求出最大值.
ans += i;
x = t[x].ch[!k];
}
else x = t[x].ch[k];
}
return ans;
}
int main() {
memset(head, -1, sizeof(head));
int n;
cin >> n;
//首先是建图,这里使用链式前向星,
for (int i = 1, u, v, w; i < n; i++) {
cin >> u >> v >> w;
add(u, v, w);//因为是无向图
add(v, u, w);
}
dfs(1, -1);//使用dfs以1号节点为根节点,计算每个节点到根节点的异或路径和值
build(n);//使用每个节点到根节点的异或和值建立01树
int ans = 0;//答案.
for (int i = 1; i <= n; ++i) {
ans = max(ans, check(sum[i], 0));//遍历从一号节点到根节点的异或和可以得到的最大值
}
cout << ans;
}