#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXN 100000
int k, val[2*MAXN-1], next[2*MAXN-1], lista[MAXN+1];
int t, *aint[MAXN+1], cati[MAXN+1], father[MAXN+1];
int schimb, acum, begin, end, unde, maxim;
int q[MAXN+1], fiuMare[MAXN+1], dad[MAXN+1], h[MAXN+1], hmax[MAXN+1], sum[MAXN+1], poz[MAXN+1], path[MAXN+1];
inline int max2(int a, int b){
if(a>b){
return a;
}
return b;
}
inline void swap(int *a, int *b){
int aux=(*a);
(*a)=(*b);
(*b)=aux;
}
inline void adauga(int x, int y){
k++;
val[k]=y;
next[k]=lista[x];
lista[x]=k;
}
void dfs(int tata, int nod){
int p=lista[nod];
fiuMare[nod]=0;
dad[nod]=tata;
h[nod]=h[tata]+1;
sum[nod]=1;
while(p){
if(val[p]!=tata){
dfs(nod, val[p]);
sum[nod]+=sum[val[p]];
if(sum[fiuMare[nod]]<sum[val[p]]){
fiuMare[nod]=val[p];
}
}
p=next[p];
}
if(fiuMare[nod]){
hmax[nod]=hmax[fiuMare[nod]];
}else{
hmax[nod]=h[nod];
}
}
void HPD(int nod){
int acum, cine, i, p;
t++;
acum=t;
cati[acum]=(hmax[nod]-h[nod]+1);
aint[acum]=malloc(4*cati[acum]*sizeof(int));
//memset(aint[acum], 0, 4*cati[acum]*sizeof(int));
father[acum]=dad[nod];
cine=nod;
for(i=0; i<cati[acum]; i++){
poz[cine]=i;
path[cine]=acum;
p=lista[cine];
while(p){
if((val[p]!=dad[cine])&&(val[p]!=fiuMare[cine])){
HPD(val[p]);
}
p=next[p];
}
cine=fiuMare[cine];
}
}
void update(int p, int st, int dr){
if(st==dr){
aint[acum][p]=schimb;
return ;
}
int m=(st+dr)/2;
if(m>=unde){
update(2*p+1, st, m);
}else{
update(2*p+2, m+1, dr);
}
aint[acum][p]=max2(aint[acum][2*p+1], aint[acum][2*p+2]);
}
void query(int p, int st, int dr){
if((begin<=st)&&(dr<=end)){
maxim=max2(maxim, aint[acum][p]);
return ;
}
int m=(st+dr)/2;
if(begin<=m){
query(2*p+1, st, m);
}
if(end>=m+1){
query(2*p+2, m+1, dr);
}
}
int main(){
int n, m, i, x, y, a, b, c;
FILE *fin, *fout;
fin=fopen("heavypath.in", "r");
fout=fopen("heavypath.out", "w");
fscanf(fin, "%d%d", &n, &m);
for(i=1; i<=n; i++){
fscanf(fin, "%d", &q[i]);
}
for(i=1; i<n; i++){
fscanf(fin, "%d%d", &x, &y);
adauga(x, y);
adauga(y, x);
}
dfs(0, 1);
HPD(1);
for(i=1; i<=n; i++){
acum=path[i];
schimb=q[i];
unde=poz[i];
update(0, 0, cati[path[i]]-1);
}
for(i=0; i<m; i++){
fscanf(fin, "%d%d%d", &a, &b, &c);
if(a==0){
acum=path[b];
schimb=c;
unde=poz[b];
update(0, 0, cati[path[b]]-1);
}else{
maxim=0;
while(path[b]!=path[c]){
if(h[father[path[b]]]<h[father[path[c]]]){
swap(&b, &c);
}
acum=path[b];
begin=0;
end=poz[b];
query(0, 0, cati[path[b]]-1);
b=father[path[b]];
}
acum=path[b];
begin=poz[b];
end=poz[c];
if(begin>end){
swap(&begin, &end);
}
query(0, 0, cati[path[b]]-1);
fprintf(fout, "%d\n", maxim);
}
}
fclose(fin);
fclose(fout);
return 0;
}