#include<bits/stdc++.h>
using namespace std;
int n,dis[100005],val[100005],tag[100005],ans;
struct EDGE{
int x,y,w;
};vector <EDGE> edge;
inline bool Tuesday(EDGE A,EDGE B){return A.w<B.w;}
struct DSU{
int f[100005];
inline void init(){for(int i=1;i<=n;i++)f[i]=i;return;}
inline int find(int x){
return f[x]==x?x:f[x]=find(f[x]);
}
}dsu;
struct DFZ{
int crt,siz[100005],vis[100005],sz;
struct line{
int y,w;
};vector <line> to[100005];
inline void rana(int x,int last){
siz[x]=1;int maxn=0;
for(auto [y,w]:to[x]){
if(vis[y]||y==last)continue;
rana(y,x);if(crt)return;
siz[x]+=siz[y],maxn=max(maxn,siz[y]);
}maxn=max(maxn,sz-siz[x]);
if(maxn<=sz/2){
crt=x,siz[last]=sz-siz[x];
}return;
}
inline void find(int x,int last){
crt=0,rana(x,last);return;
}
}T1,T2;
struct SLPF{
int dep[100005],fa[100005],siz[100005],mxs[100005],top[100005],dfn[100005],cnt;
inline void dfs1(int x,int last){
dep[x]=dep[last]+1,fa[x]=last,siz[x]=1;
for(auto [y,w]:T2.to[x]){
if(y==last)continue;
dis[y]=dis[x]+w,dfs1(y,x),siz[x]+=siz[y];
if(siz[y]>siz[mxs[x]])mxs[x]=y;
}return;
}
inline void dfs2(int x,int last){
dfn[x]=++cnt,top[x]=last;
if(!mxs[x])return;dfs2(mxs[x],last);
for(auto [y,w]:T2.to[x]){
if(y!=fa[x]&&y!=mxs[x])dfs2(y,y);
}return;
}
inline int lca(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
x=fa[top[x]];
}if(dep[x]>dep[y])swap(x,y);return x;
}
}sp;
inline void init(){
sp.dfs1(1,0),sp.dfs2(1,1);
for(int i=1;i<=n;i++){
T2.to[i].clear();
}return;
}
vector <pair<int,int>> e;
inline void push(int x,int last,int dist){
if(tag[x])e.push_back({val[x]+dist,x});
for(auto [y,w]:T2.to[x]){
if(!T2.vis[y]&&y!=last)push(y,x,dist+w);
}return;
}
inline void calc(int x){
T2.vis[x]=1;
e.clear(),push(x,0,0);
sort(e.begin(),e.end());
for(int i=1;i<e.size();i++){
edge.push_back({e[0].second,e[i].second,e[0].first+e[i].first});
}
for(auto [y,w]:T2.to[x]){
if(T2.vis[y])continue;
T2.sz=T2.siz[y],T2.find(y,x),calc(T2.crt);
}return;
}
vector <int> vec;
int tmp[200005];
inline bool cmp(int x,int y){return sp.dfn[x]<sp.dfn[y];}
inline void build(){
sort(vec.begin(),vec.end(),cmp),tmp[0]=0;
for(int i=0;i<vec.size();i++){
tmp[++tmp[0]]=vec[i],tag[vec[i]]=1;
if(i+1<vec.size())tmp[++tmp[0]]=sp.lca(vec[i],vec[i+1]);
}sort(tmp+1,tmp+1+tmp[0],cmp);
tmp[0]=unique(tmp+1,tmp+1+tmp[0])-tmp-1;
for(int i=1;i<tmp[0];i++){
int LCA=sp.lca(tmp[i],tmp[i+1]);
T2.to[LCA].push_back({tmp[i+1],dis[tmp[i+1]]-dis[LCA]});
T2.to[tmp[i+1]].push_back({LCA,dis[tmp[i+1]]-dis[LCA]});
}
T2.sz=tmp[0],T2.find(tmp[1],0),calc(T2.crt);
for(int i:vec)tag[i]=0;
for(int i=1;i<tmp[0];i++){
T2.vis[tmp[i]]=T2.vis[tmp[i+1]]=0;
T2.to[sp.lca(tmp[i],tmp[i+1])].clear();
T2.to[tmp[i+1]].clear();
}return;
}
inline void insert(int x,int last,int dist){
vec.push_back(x),val[x]=dist;
for(auto [y,w]:T1.to[x]){
if(!T1.vis[y]&&y!=last)insert(y,x,dist+w);
}return;
}
inline void solve(int x){
T1.vis[x]=1,vec={x},val[x]=0;
for(auto [y,w]:T1.to[x]){
if(!T1.vis[y])insert(y,x,w);
}build();
for(auto [y,w]:T1.to[x]){
if(T1.vis[y])continue;
T1.sz=T1.siz[y],T1.find(y,x),solve(T1.crt);
}return;
}
inline int read(){
register int x(0),t(0);
static char ch=getchar();
while(!isdigit(ch)){t|=(ch=='-');ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return t?-x:x;
}
signed main(){
n=read();
for(int i=1;i<n;i++){
int x=read(),y=read(),w=read();
T1.to[x].push_back({y,w}),T1.to[y].push_back({x,w});
}
for(int i=1;i<n;i++){
int x=read(),y=read(),w=read();
T2.to[x].push_back({y,w}),T2.to[y].push_back({x,w});
}
init(),dsu.init();
T1.sz=n,T1.find(1,0),solve(T1.crt);
sort(edge.begin(),edge.end(),Tuesday);
for(auto [x,y,w]:edge){
if(dsu.find(x)!=dsu.find(y)){
dsu.f[dsu.find(x)]=dsu.find(y),ans+=w;
}
}
cout<<ans;
return 0;
}