#include #include using namespace std; using ll=int64_t; #define int ll #define FOR(i,a,b) for(int i=int(a);i CerrDummy& operator<<(CerrDummy&cd,const T&){ return cd; } using charTDummy=char; using traitsDummy=char_traits; CerrDummy& operator<<(CerrDummy&cd,basic_ostream&(basic_ostream&)){ return cd; } #define cerr cerrDummy #endif #define REACH cerr<<"reached"<; using vi=vector; using ld=long double; template ostream& operator<<(ostream& os,const pair& p){ os<<"("< ostream& operator <<(ostream& os,const vector& v){ os<<"{"; REP(i,(int)v.size()){ if(i)os<<","; os< void chmax(T& a,U b){ if(a void chmin(T& a,U b){ if(b T Sq(const T& t){ return t*t; } #define CAPITAL void Yes(bool ex=true){ #ifdef CAPITAL cout<<"YES"< tr[Nmax]; int TreeSize(int v,int p){ int ret=x[v]; for(auto e:tr[v])if(e.to!=p) ret+=TreeSize(e.to,v); return ret; } int FindCentroid(int v,int p,int s,int&c){ int ret=x[v],mx=0; for(auto e:tr[v])if(e.to!=p){ int f=FindCentroid(e.to,v,s,c); if(f==-1) return -1; else{ ret+=f; mx=max(mx,f); } } mx=max(mx,s-ret); if(mx*2<=s){ c=v; return -1; }else return ret; } int dfs(int v,int p,int d){ int res=x[v]*d; for(auto e:tr[v]){ if(e.to!=p){ res+=dfs(e.to,v,d+e.cost); } } return res; } void Solve(int root){ int ts=TreeSize(root,-1); if(ts==1){ print(0); return; } FindCentroid(root,-1,ts,root); print(dfs(root,-1,0)); } signed main(){ int n=read(),q=read(); REP(i,n) x[i]=1; assert(n<=1000); vector> es; REP(_,q){ int t=read(); if(t==1){ int a=read()-1,b=read()-1,c=read(); es.PB(make_tuple(a,b,c)); }else if(t==2){ int a=read()-1,b=read()-1; auto itr=es.begin(); while(pi(get<0>(*itr),get<1>(*itr))!=pi(a,b)) itr++; es.erase(itr); }else if(t==3){ int root=read()-1; x[root]^=1; REP(i,n) tr[i].clear(); for(auto e:es){ int a=get<0>(e),b=get<1>(e),c=get<2>(e); tr[a].PB(Edge{b,c}); tr[b].PB(Edge{a,c}); } Solve(root); }else{ assert(false); } } }