int main(){ int u,a,b,w,c; scanf("%d %d %d\n",&n,&q,&cur); for(int i=1;i<n;++i){ a=getn(), b=getn(), w=getn(); add(a,b,w); add(b,a,w); road[i][0]=a; road[i][1]=b; road[i][2]=w; } predfs(1,0); for(int i=1;i<n;++i){ w=road[i][2]; road[i][2]=0; change(i,w); } for(int i=1;i<=q;++i){ c=getn(); if(!c){ u=getn(); printf("%d\n",ask(cur,u)); cur=u; }else{ a=getn(), b=getn(); change(a,b); road[a][2]=b; } } return 0; }
void predfs(int x) { s[x] = 1; z[x] = 0; for (int i = h[x]; i; i = e[i].next) { if (e[i].node == f[x]) continue; f[e[i].node] = x; d[e[i].node] = d[x] + 1; predfs(e[i].node); s[x] += s[e[i].node]; if (s[e[i].node] > s[z[x]]) z[x] = e[i].node; } }
void predfs(int now, int deep){ dep[now]=deep; vis[now]=1; stack[++snum]=now; tree[++tnum]=now; tapp[now]=tnum; if(!app[now]) app[now]=snum; for(Edge *tmp=edge[now];tmp;tmp=tmp->next){ if(!vis[tmp->v]){ predfs(tmp->v,deep+1); stack[++snum]=now; son[now]+=son[tmp->v]+1; } } }
int main() { freopen("J.in", "r", stdin); while (scanf("%d%d", &n, &m) == 2) { tot = wsum = cnt = 0; std::fill(h + 1, h + n + 1, 0); std::fill(bit[0] + 1, bit[0] + n + 1, 0); std::fill(bit[1] + 1, bit[1] + n + 1, 0); for (int i = 1; i <= n; i++) { scanf("%d", w + i); wsum = (wsum + w[i]) % MOD; } for (int i = 1; i < n; i++) { int x, y; scanf("%d%d", &x, &y); addedge(x, y); } predfs(1); getanc(1, 1); for (int i = 1; i <= n; i++) modify(i, w[i]); for (int i = 1; i <= m; i++) { int op, x, y; scanf("%d%d%d", &op, &x, &y); if (op == 1) { int delta = (y - w[x]) % MOD; wsum = (wsum + delta) % MOD; modify(x, delta); w[x] = y; } else{ int answer = query(x, y); answer = (1ll * wsum * wsum % MOD - answer) % MOD; answer = (answer % MOD + MOD) % MOD; printf("%d\n", answer); } } } return 0; }