#include <bits/stdc++.h>
using namespace std;
template<int n, typename T, typename Updater>
class Aint {
private:
T neutralQry, initval;
T *aint;
Updater upd;
public:
Aint(T _neutralQry, T _initval) {
initval = _initval;
neutralQry = _neutralQry;
aint = new T[1 + 4 * n];
for(int i = 0; i <= 4 * n; ++i)
aint[i] = initval;
}
void update(int poz, T val, int l = 1, int r = n, int nod = 1) {
if(poz < l || r < poz)
return ;
if(l == r && l == poz)
aint[nod] = upd.update(aint[nod], val);
int mid = (l + r) / 2;
if(l < r) {
update(poz, val, l, mid, 2 * nod);
update(poz, val, mid + 1, r, 2 * nod + 1);
aint[nod] = upd.query(aint[2 * nod], aint[2 * nod + 1]);
}
}
T query(int i, int j, int l = 1, int r = n, int nod = 1) {
if(r < i || j < l || r < l)
return neutralQry;
if(i <= l && r <= j)
return aint[nod];
int mid = (l + r) / 2;
return upd.query(query(i, j, l, mid, 2 * nod),
query(i, j, mid + 1, r, 2 * nod + 1));
}
};
const int MAX_N = 100000;
vector<int> graph[MAX_N];
struct Upd {
static inline int update(int a, int b) {
return b;
}
static inline int query(int a, int b) {
return std::max(a, b);
}
};
Aint<MAX_N, int, Upd> aint(-1, -1);
int v[1+MAX_N];
int heavyId[1+MAX_N], head[1+MAX_N], depth[1+MAX_N], parent[1+MAX_N], lastid;
int subarb[1+MAX_N];
void dfs(int nod, int papa = 0) {
subarb[nod] = 1;
parent[nod] = papa;
for(auto it: graph[nod])
if(it != papa) {
depth[it] = depth[nod] + 1;
dfs(it, nod);
subarb[nod] += subarb[it];
}
}
void heavyTraversal(int nod, int headCh, int papa = 0) {
int heavySon = -1;
head[nod] = headCh;
heavyId[nod] = ++lastid;
for(auto it: graph[nod])
if(it != papa) {
if(heavySon == -1)
heavySon = it;
else if(subarb[it] > subarb[heavySon])
heavySon = it;
}
if(heavySon != -1)
heavyTraversal(heavySon, headCh, nod);
for(auto it: graph[nod])
if(it != heavySon && it != papa)
heavyTraversal(it, it, nod);
}
int heavyQuery(int u, int v) {
if(head[u] == head[v]) {
if(depth[u] > depth[v])
std::swap(u, v);
return aint.query(heavyId[u], heavyId[v]);
} else {
if(depth[head[u]] < depth[head[v]])
std::swap(u, v);
return std::max(aint.query(heavyId[head[u]], heavyId[u]),
heavyQuery(parent[head[u]], v));
}
}
int main() {
#ifdef HOME
FILE *fin = fopen("input.in", "r");
FILE *fout = fopen("output.out", "w");
#else
FILE *fin = fopen("heavypath.in", "r");
FILE *fout = fopen("heavypath.out", "w");
#endif
int n, m, a, b;
fscanf(fin, "%d%d", &n, &m);
for(int i = 1; i <= n; ++i)
fscanf(fin, "%d", &v[i]);
for(int i = 0; i < n - 1; ++i) {
fscanf(fin, "%d%d", &a, &b);
graph[a].push_back(b);
graph[b].push_back(a);
}
dfs(1);
heavyTraversal(1, 1);
for(int i = 1; i <= n; ++i)
aint.update(heavyId[i], v[i]);
for(int i = 0; i < m; ++i) {
int t, x, y;
fscanf(fin, "%d%d%d", &t, &x, &y);
if(t == 0)
aint.update(heavyId[x], y);
else
fprintf(fout, "%d\n", heavyQuery(x, y));
}
#ifdef HOME
fclose(fin);
fclose(fout);
#endif
return 0;
}