#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; vector G2[MAX]; int vs[MAX*2]; int depth[MAX*2]; int id[MAX]; void dfs(int v,int p,int d,int &k){ id[v]=k; vs[k]=v; depth[k++]=d; for(int to:G2[v]){ if(to==p) continue; dfs(to,v,d+1,k); vs[k]=v; depth[k++]=d; } //cout<; int n,logn; vector> dat; vector loglen; vector depthsv; SparseTable(int n_){ n=1; logn=1; while(n(1<<(j+1))) j++; } dat.resize(logn); for(int i=0;i x){ auto [d,id]=x; dat[0][j]=id; depthsv[id]=d; } void built(){ for(int i=1;i=n+1) vr=n+2; else vr=dat[i-1][j+(1<<(i-1))]; if(depthsv[vla]=r){ return -1; }else{ T vla=dat[loglen[r-l]][l],vr=dat[loglen[r-l]][r-(1< > 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+1 idx,cn,omo; vector dp; vvii T; AuxiliaryTree(int n):super(n),idx(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){ int d=dd(u,v); T[u].emplace_back(mp(v,d)); T[v].emplace_back(mp(u,d)); } using super::dep; void query(vector &vs){ /* assert(!vs.empty()); sort(vs.begin(),vs.end(), [&](int a,int b){return idx[a]1){ int c=st.back();st.pop_back(); add_aux_edge(st.back(),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]+=(ll)cn[to]*dd; cn[u]+=cn[to]; } } void solve(int u,int p){ dp[u]=0; for(auto [to,dd]:T[u]){ dp[u]+=dp[to]; dp[u]+=(ll)cn[to]*dd; } ans+=dp[u]*omo[u]; //cout< &ws){ for(int w:ws){ cn[w]=0; omo[w]=0; dp[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); } } vi use; vvii Y; int tim; array pos[MAX][20]; int poscur[MAX]; void calc(vii S){ if(si(S)<=1) return; for(int j=0;j>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--; G2[a].pb(b); G2[b].pb(a); AT.add_edge(a,b); } AT.build(); init(); spa=SparseTable(2*N-1); for(int i=0;i<2*N-1;i++){ spa.set(i,mp(depth[i],vs[i])); } spa.built(); solve_subproblem(0,-1); solve(); ans*=2; cout<