#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
vector <int> v[N];
vector <int> lant[N];
vector <int> Arb[N];
int n, m, nrl;
int wlant[N], val[N], s[N], TT[N], H[N], TT_lant[N], pos[N];
inline void dfs(int nod, int niv){
H[nod] = niv;
bool frunza = 1;
int Max = 0, w = 0;
for(auto it : v[nod]){
if(it == TT[nod]) continue ;
frunza = 0;
TT[it] = nod;
dfs(it, niv + 1);
s[nod] += s[it];
if(s[it] > Max) Max = s[it], w = it;
}
if(frunza){ ///cazul cand e frunza
s[nod] = 1;
wlant[nod] = ++nrl;
lant[nrl].push_back(nod);
return ;
}
///cazul cand nu e frunza
int wl = 0;
wlant[nod] = wl = wlant[w];
lant[wl].push_back(nod);
for(auto it : v[nod]){
if(it == TT[nod]) continue ;
TT_lant[it] = wl;
}
}
void build(int i, int st, int dr, int nod){
if(st == dr){
Arb[i][nod] = val[lant[i][st - 1]];
return ;
}
int mij = (st + dr) / 2;
build(i, st, mij, nod * 2);
build(i, mij + 1, dr, nod * 2 + 1);
Arb[i][nod] = max(Arb[i][nod * 2], Arb[i][nod * 2 + 1]);
}
void update(int i, int st, int dr, int nod, int x, int y){
if(st == dr){
Arb[i][nod] = y;
return ;
}
int mij = (st + dr) / 2;
if(x <= mij) update(i, st, mij, nod * 2, x, y);
else update(i, mij + 1, dr, nod * 2 + 1, x, y);
Arb[i][nod] = max(Arb[i][nod * 2], Arb[i][nod * 2 + 1]);
}
int query(int i, int st, int dr, int nod, int x, int y){
if(x <= st && dr <= y) return Arb[i][nod];
int mij = (st + dr) / 2, Sol = 0;
if(x <= mij) Sol = query(i, st, mij, nod * 2, x, y);
if(mij + 1 <= y) Sol = max(Sol, query(i, mij + 1, dr, nod * 2 + 1, x, y));
return Sol;
}
int ans(int x, int y){
int Sol = 0;
while(1){
int lx = wlant[x], ly = wlant[y];
if(lx == ly){
int st = min(pos[x], pos[y]);
int dr = max(pos[x], pos[y]);
Sol = max(Sol, query(lx, 1, lant[lx].size(), 1, st, dr));
break ;
}
if(H[lant[lx][0]] < H[lant[ly][0]]) swap(x, y), swap(lx, ly);
Sol = max(Sol, query(lx, 1, lant[lx].size(), 1, 1, pos[x]));
x = lant[lx][0];
x = TT[x];
}
return Sol;
}
int main()
{
freopen("heavypath.in", "r", stdin);
freopen("heavypath.out", "w", stdout);
scanf("%d%d", &n, &m);
for(int i = 1; i <= n ; ++i) scanf("%d", &val[i]);
int x, y;
for(int i = 1; i < n ; ++i){
scanf("%d%d", &x, &y);
v[x].push_back(y);
v[y].push_back(x);
}
dfs(1, 0);
for(int i = 1; i <= nrl ; ++i){
reverse(lant[i].begin(), lant[i].end());
Arb[i].resize(lant[i].size() * 4 + 5);
build(i, 1, lant[i].size(), 1);
int NR = 0;
for(int it : lant[i])
pos[it] = ++NR;
}
int tip;
for(int i = 1; i <= m ; ++i){
scanf("%d%d%d", &tip, &x, &y);
if(tip == 0) update(wlant[x], 1, lant[wlant[x]].size(), 1, pos[x], y);
else printf("%d\n", ans(x, y));
}
return 0;
}