#include <iostream>
#include <vector>
#include <set>
#include <fstream>
using namespace std;
ifstream fin ("heavypath.in");
ofstream fout ("heavypath.out");
const int maxN = 1e5 + 5;
vector <int> g[maxN], subTree[maxN], euler;
int level[maxN], parent[maxN], sSize[maxN], id[maxN], head[maxN], v[maxN];
int arb[4*maxN];
void update (int k, int st, int dr, int poz, int val) {
if(st == dr && st == poz) {
arb[k] = val;
return ;
}
int mij = (st + dr) / 2;
if(poz <= mij)
update(k*2, st, mij, poz, val);
else
update(k*2+1, mij+1, dr, poz, val);
arb[k] = max(arb[k*2], arb[k*2+1]);
}
int query (int k, int st, int dr, int l, int r) {
if(l <= st && dr <= r)
return arb[k];
int mij = (st + dr) / 2;
if(r <= mij)
return query(k*2, st, mij, l, r);
else if(l > mij)
return query(k*2+1, mij+1, dr, l, r);
else
return max(query(k*2, st, mij, l, r),
query(k*2+1, mij+1, dr, l, r));
}
void compute (int node, int dad = 0) {
level[node] = level[dad] + 1;
parent[node] = dad;
sSize[node] = 1;
for(int to : g[node]) {
if(to != dad) {
compute(to, node);
sSize[node] += sSize[to];
subTree[node].push_back(to);
}
}
}
void heavyDfs (int node) {
euler.push_back(node);
id[node] = euler.size();
if(subTree[node].size() == 0)
return ;
int heavySon = subTree[node][0];
for(int to : subTree[node])
if(sSize[to] > sSize[heavySon])
heavySon = to;
head[heavySon] = head[node];
heavyDfs(heavySon);
for(int to : subTree[node])
if(to != heavySon)
heavyDfs(to);
}
int solve (int u, int v, int n) {
if(head[u] == head[v]) {
return query(1, 1, n, min(id[u], id[v]), max(id[u], id[v]));
}
//cout << u << " " << v << " -> ";
int ans = 0;
if(level[parent[head[u]]] > level[parent[head[v]]]) {
ans = query(1, 1, n, id[head[u]], id[u]);
u = parent[head[u]];
} else {
ans = query(1, 1, n, id[head[v]], id[v]);
v = parent[head[v]];
}
//cout << ans << " -> " <<u << " " << v << '\n';
return max(ans, solve(u, v, n));
}
signed main() {
int n, q; fin >> n >> q;
for(int i = 1; i <= n; i++) {
fin >> v[i];
head[i] = i;
}
for(int i = 1; i < n; i++) {
int u, v; fin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
compute (1);
heavyDfs(1);
for(int i = 1; i <= n; i++)
update(1, 1, n, id[i], v[i]);
for(int i = 1; i <= q; i++) {
int op; fin >> op;
if(op == 0) {
int poz, val; fin >> poz >> val;
update(1, 1, n, id[poz], val);
} else {
int a, b; fin >> a >> b;
fout << solve(a, b, n) << "\n";
}
}
return 0;
}