#include using namespace std; typedef unsigned long long ll; templatebool chmax(T &a, const T &b) { if (abool chmin(T &a, const T &b) { if (b #define vl vector #define vii vector> #define vll vector> #define vvi vector> #define vvl vector> #define vvii vector>> #define vvll vector>> #define vst vector #define pii pair #define pll pair #define pb push_back #define all(x) (x).begin(),(x).end() #define mkunique(x) sort(all(x));(x).erase(unique(all(x)),(x).end()) #define fi first #define se second #define mp make_pair #define si(x) int(x.size()) const int mod=998244353,MAX=200005,INF=15<<26; ll ans=0; //auxiliary-tree // https://beet-aizu.github.io/library/tree/auxiliarytree.cpp.html struct LowestCommonAncestor{ int h; vector< vector > G,par; vector dep; LowestCommonAncestor(int n):G(n),dep(n){ h=1; while((1<(n,-1)); } void add_edge(int u,int v){ G[u].emplace_back(v); G[v].emplace_back(u); } void dfs(int v,int p,int d){ par[0][v]=p; dep[v]=d; for(int u:G[v]) if(u!=p) dfs(u,v,d+1); } void build(int r=0){ int n=G.size(); dfs(r,-1,0); for(int k=0;k+1dep[v]) swap(u,v); for(int k=0;k>k&1) v=par[k][v]; if(u==v) return u; for(int k=h-1;k>=0;k--) if(par[k][u]!=par[k][v]) u=par[k][u],v=par[k][v]; return par[0][u]; } int distance(int u,int v){ return dep[u]+dep[v]-dep[lca(u,v)]*2; } }; struct AuxiliaryTree : LowestCommonAncestor{ using super = LowestCommonAncestor; vector idx,iru; vl cn,omo,dp; vvll T; AuxiliaryTree(int n):super(n),idx(n),iru(n),cn(n),omo(n),dp(n),T(n){} void dfs(int v,int p,int &pos){ idx[v]=pos++; for(int u:G[v]) if(u!=p) dfs(u,v,pos); } void build(int r=0){ super::build(r); int pos=0; dfs(r,-1,pos); } void add_aux_edge(int u,int v){ T[u].emplace_back(mp(v,distance(u,v))); T[v].emplace_back(mp(u,distance(u,v))); } using super::lca, super::dep; void query(vector &vs){ assert(!vs.empty()); sort(vs.begin(),vs.end(), [&](int a,int b){return idx[a] st; st.emplace(vs[0]); for(int i=0;i+11){ int c=st.top();st.pop(); add_aux_edge(st.top(),c); } } void make(int u,int p){ for(auto [to,dd]:T[u]){ if(to==p) continue; make(to,u); dp[u]+=dp[to]; dp[u]+=cn[to]*dd; cn[u]+=cn[to]; } } void solve(int u,int p){ if(iru[u]) cn[u]=1; else cn[u]=0; dp[u]=0; for(auto [to,dd]:T[u]){ dp[u]+=dp[to]; dp[u]+=cn[to]*dd; cn[u]+=cn[to]; } ans+=dp[u]*omo[u]; //cout< &ws){ for(int w:ws){ cn[w]=0; omo[w]=0; dp[w]=0; iru[w]=0; T[w].clear(); } } }; AuxiliaryTree AT(1); //重心分解(使える版) int N,C=-1; vi G[MAX]; bool centroid[MAX]; int subtree_size[MAX]; int centpar[MAX]; int compute_subtree_size(int u,int p){ int c=1; for(int a:G[u]){ if(a==p||centroid[a]) continue; c+=compute_subtree_size(a,u); } return subtree_size[u]=c; } pair search_centroid(int u,int p,int t){ pair res={INF,-1}; int s=1,m=0; for(int a:G[u]){ if(a==p||centroid[a]) continue; res=min(res,search_centroid(a,u,t)); m=max(m,subtree_size[a]); s+=subtree_size[a]; } m=max(m,t-s); res=min(res,{m,u}); return res; } void atume(int u,int p,int d,vii &T){ T.pb(mp(d,u)); for(int to:G[u]){ if(to==p||centroid[to]) continue; atume(to,u,d+1,T); } } void calc(vii S,int kei){ if(si(S)<=1) return; vi use; for(auto [a,b]:S) use.pb(b); AT.query(use); for(auto [a,b]:S){ AT.iru[b]=1; AT.omo[b]=a*kei; AT.cn[b]=1; } AT.make(use[0],-1); AT.solve(use[0],-1); AT.clear(use); } void solve_subproblem(int u,int p){ compute_subtree_size(u,-1); int s=search_centroid(u,-1,subtree_size[u]).second; centroid[s]=1; if(C==-1) C=s; centpar[s]=p; vii S={mp(0,s)}; for(int a:G[s]){ if(centroid[a]){ continue; } vii T; atume(a,s,1,T); calc(T,-1); for(auto x:T) S.pb(x); solve_subproblem(a,s); } calc(S,1); centroid[s]=0; } int main(){ std::ifstream in("text.txt"); std::cin.rdbuf(in.rdbuf()); cin.tie(0); ios::sync_with_stdio(false); cin>>N; for(int i=0;i>a>>b; a--;b--; G[a].pb(b); G[b].pb(a); } AT=AuxiliaryTree(N); for(int i=0;i>a>>b; a--;b--; AT.add_edge(a,b); } AT.build(); solve_subproblem(0,-1); ans*=2; cout<