#include using namespace std; typedef long long ll; template void check_min(T &a, const T &b){ a = (a < b) ? a : b; } template void check_max(T &a, const T &b){ a = (a > b) ? a : b; } #define all(x) (x).begin(), (x).end() const ll N = 1e6 + 3; ll n, q; vector> adj[N]; array edges[N]; ll a[N]; vector> queries, updates; ll ans[N]; struct DynamicSegmentTree{ vector sum; vector l_ch, r_ch; DynamicSegmentTree(){ sum.push_back(0); l_ch.push_back(-1); r_ch.push_back(-1); } void update(ll idx, ll v, ll i = 0, ll l = 0, ll r = q - 1){ if(idx < l || r < idx) return; if(l == r){ sum[i] += v; return; } ll mid = (l + r) >> 1; if(l <= idx <= mid){ if(l_ch[i] == -1){ sum.push_back(0); l_ch.push_back(-1); r_ch.push_back(-1); l_ch[i] = l_ch.size() - 1; } update(idx, v, l_ch[i], l, mid); } else{ if(r_ch[i] == -1){ sum.push_back(0); l_ch.push_back(-1); r_ch.push_back(-1); r_ch[i] = r_ch.size() - 1; } update(idx, v, r_ch[i], mid + 1, r); } sum[i] = 0; if(l_ch[i] != -1) sum[i] += sum[l_ch[i]]; if(r_ch[i] != -1) sum[i] += sum[r_ch[i]]; } ll query(ll sl, ll sr, ll i = 0, ll l = 0, ll r = q - 1){ if(sr < l || r < sl) return 0ll; if(sl <= l && r <= sr) return sum[i]; ll mid = (l + r) >> 1; ll ans = 0; if(l_ch[i] != -1) ans += query(sl, sr, l_ch[i], l, mid); if(r_ch[i] != -1) ans += query(sl, sr, r_ch[i], mid + 1, r); return ans; } }; struct DSU{ ll sz[N], p[N]; ll sum[N]; DynamicSegmentTree st[N]; vector> st_upd[N]; ll get_p(ll x){ if(x == p[x]) return x; return p[x] = get_p(p[x]); } } dsu; void merge(ll u, ll v){ u = dsu.get_p(u); v = dsu.get_p(v); if(dsu.sz[u] + dsu.st_upd[u].size() * 20 < dsu.sz[v] + dsu.st_upd[v].size() * 20) swap(u, v); dsu.sz[u] += dsu.sz[v]; dsu.p[v] = u; dsu.sum[u] += dsu.sum[v]; for(auto upd: dsu.st_upd[v]){ dsu.st_upd[u].push_back(upd); dsu.st[u].update(upd.first, upd.second); } } int main(){ ios::sync_with_stdio(false); cin.tie(NULL); freopen("thief.in", "r", stdin); freopen("thief.out", "w", stdout); cin >> n >> q; for(ll i = 1; i <= n; ++i) cin >> a[i]; for(ll i = 1; i <= n; ++i){ dsu.sz[i] = 1; dsu.p[i] = i; dsu.sum[i] = a[i]; } for(ll i = 0; i < n - 1; ++i){ ll a, b, c; cin >> a >> b >> c; edges[i] = {c, a, b}; adj[a].push_back({b, c}); adj[b].push_back({a, c}); } sort(edges, edges + n - 1); for(ll i = 0; i < q; ++i){ ll t; cin >> t; if(t == 1){ queries.push_back({}); for(ll j = 0; j < 2; ++j) cin >> queries.back()[!j]; queries.back()[2] = i; } else{ updates.push_back({}); for(ll j = 0; j < 2; ++j) cin >> updates.back()[j]; updates.back()[2] = i; } } for(auto [x, l, i]: updates){ ll change = l - a[x]; a[x] = l; dsu.st_upd[x].push_back({i, change}); dsu.st[x].update(i, change); } sort(all(queries)); ll ptr_q = 0; for(ll i = 0; i < n; ++i){ //cout << i << " i" << endl; while(ptr_q < queries.size() && (i == n - 1 || queries[ptr_q][0] < edges[i][0])){ //cout << "query " << queries[ptr_q][0] << " " << queries[ptr_q][1] << " " << queries[ptr_q][2] << "\n"; ll p = dsu.get_p(queries[ptr_q][1]); ans[queries[ptr_q][2]] = dsu.sum[p] + dsu.st[p].query(0, queries[ptr_q][2]); ++ptr_q; } if(i == n - 1) break; merge(edges[i][1], edges[i][2]); //cout << "merge " << edges[i][1] << " " << edges[i][2] << "\n"; } sort(all(queries), [&](auto l, auto r){ return l[2] < r[2]; }); for(auto [a, b, c]: queries) cout << ans[c] << "\n"; return 0; }