#include <bits/stdc++.h>
using namespace std;
#define ST_DIO 0
#if ST_DIO
#define fin cin
#define fout cout
#else
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
#endif // ST_DIO
int n, q, i, val[100002];
vector<int> gr[100002];
int aint[2 * 100002];
int niv[100002];
int tata[100002];
int subArb[100002];
int cap[100002];
int timp[100002];
static inline void UpdateAINT(int nod, int st, int dr, int poz, int val) {
if(st == dr) aint[nod] = val;
else {
int mij = st + (dr - st) / 2;
int nodSt = nod + 1;
int nodDr = nod + 2 * (mij - st + 1);
if(poz <= mij) UpdateAINT(nodSt, st, mij, poz, val);
else UpdateAINT(nodDr, mij + 1, dr, poz, val);
aint[nod] = max(aint[nodSt], aint[nodDr]);
}
}
static inline int QueryAINT(int nod, int st, int dr, int qst, int qdr) {
if(qst <= st && dr <= qdr) return aint[nod];
else {
int mij = st + (dr - st) / 2;
int nodSt = nod + 1;
int nodDr = nod + 2 * (mij - st + 1);
int q1 = 0, q2 = 0;
if(qst <= mij) q1 = QueryAINT(nodSt, st , mij, qst, qdr);
if(mij < qdr) q2 = QueryAINT(nodDr, mij + 1, dr , qst, qdr);
return max(q1, q2);
}
}
static inline void DFSInit(int nod = 1, int ant = 0) {
tata[nod] = ant;
niv[nod] = niv[ant] + 1;
subArb[nod] = 1;
for(int urm : gr[nod]) {
if(urm != ant) {
DFSInit(urm, nod);
subArb[nod] += subArb[urm];
}
}
}
int timpCur = 0;
static inline void DFSHeavy(int nod, int ant, int capCur) {
timp[nod] = ++timpCur;
cap[nod] = capCur;
int urmCur = 0;
for(int urm : gr[nod]) {
if(urm != ant) {
if(subArb[urmCur] < subArb[urm]) urmCur = urm;
}
}
if(urmCur > 0) DFSHeavy(urmCur, nod, capCur);
for(int urm : gr[nod]) {
if(urm != ant && urm != urmCur) {
DFSHeavy(urm, nod, urm);
}
}
}
static inline int QueryHeavy(int st, int dr) {
int ret = 0;
while(cap[st] != cap[dr]) {
int capSt = cap[st];
int capDr = cap[dr];
if(niv[capSt] > niv[capDr]) {
swap(st, dr);
swap(capSt, capDr);
}
ret = max(ret, QueryAINT(1, 1, n, timp[capDr], timp[dr]));
dr = tata[capDr];
}
if(niv[st] > niv[dr]) swap(st, dr);
ret = max(ret, QueryAINT(1, 1, n, timp[st], timp[dr]));
return ret;
}
int main() {
if(ST_DIO) ios_base::sync_with_stdio(false);
fin.tie(nullptr);
fout.tie(nullptr);
fin >> n >> q;
for(i = 1; i <= n; i++) fin >> val[i];
for(i = 1; i < n; i++) {
int x, y;
fin >> x >> y;
gr[x].push_back(y);
gr[y].push_back(x);
}
DFSInit(1, 0);
DFSHeavy(1, 0, 1);
for(i = 1; i <= n; i++) UpdateAINT(1, 1, n, timp[i], val[i]);
for(i = 1; i <= q; i++) {
int op, x, y;
fin >> op >> x >> y;
if(op == 0) UpdateAINT(1, 1, n, timp[x], y);
else fout << QueryHeavy(x, y) << "\n";
}
return 0;
}