#include <memory.h> #include <algorithm> #include <vector> #include <queue> #include <iostream> #include <stdio.h> #include <stack> #include <time.h> using namespace std; #define M(a) memset(a,0,sizeof(a)) typedef pair<int,int> PII; const int N = 300000+5; const int INF = -100000000; typedef __int64 LL; int max(int x,int y) { return x > y ? x : y; } class LinkCutTree { public: int ch[N][2],fa[N],pp[N],SZ[N];//path parent int Max[N],cost[N],lazy[N]; int rev[N]; int find_root(int cur) { while(fa[cur])cur = fa[cur]; return cur; } void Modify(int x,int k)//修改 { if(x == 0) return; cost[x] = cost[x] + k; Max[x] = Max[x] + k; lazy[x] = lazy[x] + k; } void Spread(int x)//伸展 { if(x == 0) return; if(lazy[x] != 0) { Modify(ch[x][0],lazy[x]); Modify(ch[x][1],lazy[x]); lazy[x] = 0; } if(rev[x] != 0) { if(ch[x][0] != 0) rev[ch[x][0]] ^=1; if(ch[x][1] != 0) rev[ch[x][1]] ^=1; swap(ch[x][0],ch[x][1]); rev[x] = 0; } } void update(int x)//更新 { Max[x] = max(cost[x],max(Max[ch[x][0]],Max[ch[x][1]])); return; } void rotate(int x,bool f)//旋转 { int y = fa[x]; ch[y][!f] = ch[x][f]; fa[ch[x][f]] = y; fa[x] = fa[y]; if(fa[x])ch[fa[y]][ch[fa[y]][1] == y] = x; ch[x][f] = y; fa[y] = x; update(y); } void splay(int x)// { Spread(x); int i1,i2,root = find_root(x); if (root == x) return; pp[x] = pp[root]; pp[root] = 0; while(fa[x]) { if(!fa[fa[x]]) { Spread(fa[x]); Spread(x); rotate(x,ch[fa[x]][0] == x); } else { int y = fa[x],z = fa[y]; Spread(z); Spread(y); Spread(x); int f = (ch[z][0] == y); if(ch[y][f] == x) { rotate(x,!f); rotate(x,f); } else { rotate(y,f); rotate(x,f); } } } update(x); } //void Rev(int x) {rev[x] ^= 1;return;} void access(int x)// { for(int pre = 0; x;) { splay(x); fa[ch[x][1]] = 0; pp[ch[x][1]] = x; ch[x][1] = pre; pp[pre] = 0; fa[pre] = x; pre = x; update(x); x = pp[x]; } } int paint_path(int a,int b,int c)// { if(a > b) swap(a,b); access(a); int ans = 0; for(int pre = 0; b;) { splay(b); if(pp[b] == 0) { Modify(pre,c); Modify(ch[b][1],c); cost[b] += c; update(b); } fa[ch[b][1]] = 0; pp[ch[b][1]] = b; ch[b][1] = pre; pp[pre] = 0; fa[pre] = b; pre = b; update(b); b = pp[b]; } return ans; } int query_path(int a,int b)// { if(a > b) swap(a,b); access(a); int ans = 0; for(int pre = 0; b;) { splay(b); if(pp[b] == 0) { ans = max(cost[b],max(Max[ch[b][1]],Max[pre])); } fa[ch[b][1]] = 0; pp[ch[b][1]] = b; ch[b][1] = pre; pp[pre] = 0; fa[pre] = b; pre = b; update(b); b = pp[b]; } return ans; } int get_root(int x)// { access(x); splay(x); while(ch[x][0]) x = ch[x][0]; return x; } void cut(int x,int y)// { if(x == y) return; access(x); splay(x); rev[x] ^=1; access(y); splay(y); pp[ch[y][0]] = pp[y]; fa[ch[y][0]] = 0; pp[y] = 0; ch[y][0] = 0; update(y); } void join(int x,int y)// { access(x); splay(x); rev[x] ^=1; access(y); splay(y); rev[y] ^=1; pp[x] = y; return; } void init() { M(ch),M(fa); M(lazy); M(rev); pp[0] = 0; Max[0] = 0; rev[0] = 0; lazy[0] = 0; } } LCT; struct Edge { int p,next; } E[3 * N]; int head[N],cnt = 0; void Init() { memset(head,-1,sizeof(head)); cnt = 0; } void add(int a,int b) { cnt++; E[cnt].p = b; E[cnt].next = head[a]; head[a] = cnt; cnt++; E[cnt].p = a; E[cnt].next = head[b]; head[b] = cnt; } int S[N],sidx; int ins[N]; void dfs() { int i,j,k; memset(ins,0,sizeof(ins)); sidx = 0; S[++sidx] = 1; LCT.pp[1] = 0; while(sidx > 0) { int cur = S[sidx]; if(ins[cur] == 0) { ins[cur] = 1; for(i = head[cur]; i != -1; i = E[i].next) { int p = E[i].p; if(ins[p] == 0) { LCT.pp[p] = cur; S[++sidx] = p; } } } else { sidx--; ins[cur] = 0; } } } inline int Scan() { int res = 0 , ch ; while( !( ( ch = getchar() ) >= '0' && ch <= '9' ) ) { if( ch == EOF ) return 1 << 30 ; } res = ch - '0' ; while( ( ch = getchar() ) >= '0' && ch <= '9' ) res = res * 10 + ( ch - '0' ) ; return res ; } int main() { int i,j,k; int n; while(scanf("%d",&n) != EOF) { LCT.init(); Init(); for(i = 1; i < n; i++) { int a,b; a = Scan(); b = Scan(); add(a,b); } int tmp; for(i = 1; i <= n; i++) { tmp = Scan(); LCT.cost[i] = tmp; LCT.Max[i] = LCT.cost[i]; } dfs(); int Q; Q = Scan(); int cmd,w,x,y; for(i = 1; i <= Q; i++) { cmd = Scan(); if(cmd == 1) { //scanf("%d %d",&x,&y); x = Scan(); y = Scan(); if(LCT.get_root(x) != LCT.get_root(y)) LCT.join(x,y); else printf("-1\n"); } else if(cmd == 2) { //scanf("%d %d",&x,&y); x = Scan(); y = Scan(); if(x != y && LCT.get_root(x) == LCT.get_root(y)) LCT.cut(x,y); else printf("-1\n"); } else if(cmd == 3) { //scanf("%d %d %d",&w,&x,&y); w = Scan(); x = Scan(); y = Scan(); if(LCT.get_root(x) == LCT.get_root(y)) { LCT.paint_path(x,y,w); } else printf("-1\n"); } else { //scanf("%d %d",&x,&y); x = Scan(); y = Scan(); if(LCT.get_root(x) == LCT.get_root(y)) printf("%d\n",LCT.query_path(x,y)); else printf("-1\n"); } } printf("\n"); } return 0; }