#include <bits/stdc++.h>
using namespace std;
#define L (nod << 1)
#define R (L | 1)
const int N = 100010;
int n, m, k, a[N], p[N], sz[N], nrlant = 1, arb[4*N], cnt[N], lvl[N], lnt[N], ord[N], bgn[N];
vector <int> v[N];
void update(int nod, int st, int dr, int idx, int val){
if (st == dr){
arb[nod] = val;
return;
}
int mid = (st + dr) >> 1;
if (idx <= mid) update(L, st, mid, idx, val);
else update(R, mid + 1, dr, idx, val);
arb[nod] = max(arb[L], arb[R]);
}
int query(int nod, int st, int dr, int l, int r){
if (st >= l && dr <= r) return arb[nod];
int mid = (st + dr) >> 1;
int left = -1, right = -1;
if (l <= mid) left = query(L, st, mid, l, r);
if (r > mid) right = query(R, mid + 1, dr, l, r);
return max(left, right);
}
int dfs(int q, int pr){
sz[q] = 1;
for(auto it: v[q])
if (it != pr) sz[q] += dfs(it, q);
return sz[q];
}
void hld(int q, int pr, int depth){
lnt[q] = nrlant;
ord[q] = ++cnt[nrlant];
lvl[lnt[q]] = depth;
//cout << q << " " << lnt[q] << "\n";
int mx = -1, mxidx = -1;
for (auto it: v[q])
if (it != pr && sz[it] > mx) mx = sz[it], mxidx = it;
if (mxidx != -1) hld(mxidx, q, depth);
for (auto it: v[q])
if (it != pr && it != mxidx)
p[++nrlant] = q, hld(it, q, depth+1);
if (ord[q] == cnt[lnt[q]]) bgn[lnt[q]] = k + 1, k += cnt[lnt[q]];
update(1, 1, n, bgn[lnt[q]] + ord[q] - 1, a[q]);
}
int main(){
ifstream cin ("heavypath.in");
ofstream cout ("heavypath.out");
cin >> n >> m;
for (int i=1; i<=n; i++) cin >> a[i];
for (int i=1, x, y; i<n; i++){
cin >> x >> y;
v[x].push_back(y);
v[y].push_back(x);
}
dfs(1, -1);
hld(1, -1, 1);
//for (int i=1; i<=n; i++) cout << i << ": " << lnt[i] << " " << bgn[lnt[i]] << '\n';
for (int i=1, o, x, y; i<=m; i++){
cin >> o >> x >> y;
if (!o) update(1, 1, n, bgn[lnt[x]] + ord[x]-1, y);
else{
int rs = -1;
if (lvl[lnt[x]] > lvl[lnt[y]]) swap(x, y);
while (lvl[lnt[y]] > lvl[lnt[x]]){
rs = max(rs, query(1, 1, n, bgn[lnt[y]], ord[y] + bgn[lnt[y]]-1));
y = p[lnt[y]];
}
while (lnt[y] != lnt[x]){
rs = max(rs, query(1, 1, n, bgn[lnt[y]], bgn[lnt[y]] + ord[y]-1));
rs = max(rs, query(1, 1, n, bgn[lnt[x]], bgn[lnt[x]] + ord[x]-1));
y = p[lnt[y]]; x = p[lnt[x]];
}
if (ord[x] > ord[y]) swap(x, y);
rs = max(rs, query(1, 1, n, bgn[lnt[x]] + ord[x]-1, bgn[lnt[x]]+ord[y]-1));
cout << rs << "\n";
}
}
return 0;
}