#include<fstream>
#include<vector>
#define DIM 100005
using namespace std;
int n, q, i, ii, jj, x, y, nr, tip, maxim;
int t[DIM], niv[DIM], poz[DIM], tl[DIM], lt[DIM], aint[4 * DIM], viz[DIM], val[DIM], ad[DIM], num[DIM];
vector<int> v[DIM], w[DIM];
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
void dfs(int nod){
int i, vecin, ii = 0;
viz[nod] = num[nod] = 1;
for(i = 0; i < v[nod].size(); i++){
int vecin = v[nod][i];
if(viz[vecin] == 0){
niv[vecin] = niv[nod] + 1;
t[vecin] = nod;
dfs(vecin);
if(num[ii] < num[vecin]){
ii = vecin;
}
num[nod] += num[vecin];
}
}
if(ii == 0){
nr++;
lt[nod] = nr;
w[nr].push_back(nod);
}
else{
lt[nod] = lt[ii];
w[ lt[nod] ].push_back(nod);
}
}
void build(int p, int nod, int st, int dr, int ad){
if(st == dr){
aint[nod + ad] = val[ w[p][st - 1] ];
}
else{
int mid = (st + dr) / 2;
build(p, 2 * nod, st, mid, ad);
build(p, 2 * nod + 1, mid + 1, dr, ad);
aint[nod + ad] = max(aint[2 * nod + ad], aint[2 * nod + 1 + ad]);
}
}
void update(int nod, int st, int dr, int ad, int p, int x){
if(st == dr){
aint[nod + ad] = x;
}
else{
int mid = (st + dr) / 2;
if(p <= mid){
update(2 * nod, st, mid, ad, p, x);
}
else{
update(2 * nod + 1, mid + 1, dr, ad, p, x);
}
aint[nod + ad] = max(aint[2 * nod + ad], aint[2 * nod + 1 + ad]);
}
}
void query(int nod, int st, int dr, int ad, int p, int u){
if(p <= st && dr <= u){
maxim = max(maxim, aint[nod + ad]);
}
else{
int mid = (st + dr) / 2;
if(p <= mid){
query(2 * nod, st, mid, ad, p, u);
}
if(u > mid){
query(2 * nod + 1, mid + 1, dr, ad, p, u);
}
}
}
int main(){
fin>> n >> q;
for(i = 1; i <= n; i++){
fin>> val[i];
}
for(i = 1; i < n; i++){
fin>> x >> y;
v[x].push_back(y);
v[y].push_back(x);
}
dfs(1);
for(i = 1; i <= nr; i++){
for(ii = 0, jj = w[i].size() - 1; ii < jj; ii++, jj--){
swap(w[i][ii], w[i][jj]);
}
tl[i] = t[ w[i][0] ];
for(ii = 0; ii < w[i].size(); ii++){
poz[ w[i][ii] ] = ii;
}
ad[i] = ad[i - 1] + 4 * w[i - 1].size();
build(i, 1, 1, w[i].size(), ad[i]);
}
for(; q; q--){
fin>> tip >> x >> y;
if(tip == 0){
update(1, 1, w[ lt[x] ].size(), ad[ lt[x] ], poz[x] + 1, y);
continue;
}
maxim = 0;
while(lt[x] != lt[y]){
ii = tl[ lt[x] ];
jj = tl[ lt[y] ];
if(niv[ii] > niv[jj]){
query(1, 1, w[ lt[x] ].size(), ad[ lt[x] ], 1, poz[x] + 1);
x = ii;
}
else{
query(1, 1, w[ lt[y] ].size(), ad[ lt[y] ], 1, poz[y] + 1);
y = jj;
}
}
if(poz[x] > poz[y]){
swap(x, y);
}
query(1, 1, w[ lt[x] ].size(), ad[ lt[x] ], poz[x] + 1, poz[y] + 1);
fout<< maxim <<"\n";
}
return 0;
}