#include <bits/stdc++.h>
using namespace std;
ifstream fin ("heavypath.in");
ofstream fout ("heavypath.out");
const int maxN = 1e5 + 5;
const int INF = 2e9;
int parent[maxN], siz[maxN], level[maxN], v[maxN], ind[maxN], head[maxN];
int arb[4 * maxN];
vector <int> g[maxN];
vector <int> subTree[maxN];
vector <int> dfsOrder;
void compute (int node, int dad = 0) {
parent[node] = dad;
siz[node] = 1;
level[node] = level[dad] + 1;
for(int to : g[node])
if(to != dad) {
compute(to, node);
subTree[node].push_back(to);
siz[node] += siz[to];
}
}
void heavyDfs(int node) {
dfsOrder.push_back(node);
ind[node] = int(dfsOrder.size());
if(subTree[node].size() == 0)
return ;
int heavySon = *(subTree[node].begin());
for(int to : subTree[node])
if(siz[heavySon] < siz[to]) {
heavySon = to;
}
head[heavySon] = head[node];
heavyDfs(heavySon);
for(int to : subTree[node])
if(to != heavySon)
heavyDfs(to);
}
void update (int pos, int val, int k, int st, int dr) {
if(st > dr) return;
if(st == dr && st == pos) {
arb[k] = val;
return;
}
int mij = (st + dr) / 2;
if(pos <= mij)
update (pos, val, k * 2, st, mij);
else
update (pos, val, k*2+1, mij+1, dr);
arb[k] = max(arb[k*2], arb[k*2+1]);
}
int query (int l, int r, int k, int st, int dr) {
if(l > r) return -INF;
if(l <= st && dr <= r) {
return arb[k];
}
int mij = (st + dr) / 2;
return max(query(l, min(mij, r), k*2, st, mij),
query(max(l, mij+1), r, k*2+1, mij+1, dr));
}
int Query(int u, int v, int n) {
if(head[u] == head[v]) { // daca fac parte din acelasi
if(ind[u] > ind[v]) // lant tare
swap(u, v);
return query(ind[u], ind[v], 1, 1, n);
}
int ans = 0;
if(level[parent[head[u]]] > level[parent[head[v]]]) {
int l = min(ind[u], ind[head[u]]);
int r = max(ind[u], ind[head[u]]);
ans = query(l, r, 1, 1, n);
u = parent[head[u]];
} else {
int l = min(ind[v], ind[head[v]]);
int r = max(ind[v], ind[head[v]]);
ans = query(l, r, 1, 1, n);
v = parent[head[v]];
}
return max(ans, Query(u, v, n));
}
int main() {
int n, m; fin >> n >> m;
for(int i = 1; i <= n; ++i)
fin >> v[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);
for(int i = 1; i <= n; ++i)
head[i] = i;
heavyDfs(1);
for(int i = 1; i <= n; ++i)
update(ind[i], v[i], 1, 1, n);
for(int i = 1; i <= m; ++i) {
int op; fin >> op;
if(op == 0) {
int pos, val; fin >> pos >> val;
update(ind[pos], val, 1, 1, n);
} else {
int l, r; fin >> l >> r;
fout << Query(l, r, n) << "\n";
}
}
return 0;
}