///树链剖分 边权
int son[maxn]; //表示该点重链的子节点
int num[maxn]; //表示以该点为根的子树的节点数量
int dep[maxn]; //表示该节点的深度
int fa[maxn]; //表示该节点的父亲节点
int vis[maxn]; //表示该节点在线段树中的编号
int top[maxn]; //表示这条重链的顶端节点
int edge[maxn][3];
int now;
void dfs1(int u,int v,int step) //第一遍dfs求出son,fa,num,dep
{
dep[v]=step,num[v]=1,fa[v]=u;
for(int i=first[v]; ~i; i=edge1[i].next)
{
int to=edge1[i].to;
if(to!=u)
{
dfs1(v,to,step+1);
num[v]+=num[to];
if(son[v]==-1||num[son[v]]<num[to])
{
son[v]=to;
}
}
}
}
void dfs2(int u,int v) // 第二遍dfs求出top和vis
{
top[v]=u,vis[v]=now++;
if(son[v]==-1)
return ;
else
dfs2(u,son[v]);
for(int i=first[v]; ~i; i=edge1[i].next)
{
int to = edge1[i].to;
if(to==fa[v]||to==son[v])
continue;
dfs2(to,to);
}
}
int Find(int y,int z)
{
int q,w;
int ans = 0;
q = top[y],w = top[z];
int f=0;
while(q != w) //不在一条重链上,就爬树
{
if(dep[q] < dep[w])
swap(q,w),swap(y,z);
if(f==0)
{
ans = query(1,vis[q]+1,vis[y]+1);
f=1;
}
else
ans = max(ans,query(1,vis[q]+1,vis[y]+1));
y = fa[q];
q = top[y];
}
if(y != z) //爬到一条重链上
{
if(dep[y] > dep[z])
swap(y,z);
if(f==0)
{
ans = query(1,vis[son[y]]+1,vis[z]+1);
f=1;
}
else
ans = max(ans,query(1,vis[son[y]]+1,vis[z]+1));
}
return ans;
}
void update(int y,int z)
{
int q,w;
q = top[y],w = top[z];
while(q != w) //不在一条重链上,就爬树
{
if(dep[q] < dep[w])
swap(q,w),swap(y,z);
update1(1,vis[q]+1,vis[y]+1);
y = fa[q];
q = top[y];
}
if(y != z) //爬到一条重链上
{
if(dep[y] > dep[z])
swap(y,z);
update1(1,vis[son[y]]+1,vis[z]+1);
}
}
void init()
{
now=0;
memset(son,-1,sizeof(son));
memset(tree,0,sizeof(tree));
}
int main()
{
init();
init_edge();
scanf("%d",&n);
for(int i=1; i<=n-1; i++)
{
scanf("%d%d%d",&edge[i][0],&edge[i][1],&edge[i][2]);
add_edge(edge[i][0],edge[i][1],edge[i][2]);
add_edge(edge[i][1],edge[i][0],edge[i][2]);
}
dfs1(1,1,1);
dfs2(1,1);
build(1,1,n);
for(int i = 1; i <= n-1; i++)
{
if(dep[edge[i][0]] < dep[edge[i][1]])
swap(edge[i][0],edge[i][1]);
update2(1,vis[edge[i][0]]+1,edge[i][2]);
}
///区间查询,更新
printf("%d\n",Find(l,r));
update(l,r);
}