#include<fstream>
#include<algorithm>
using namespace std;
typedef struct celula {
int nod;
celula *next;
}*lista;
lista arb[100005],aux[100005],v;
int i,n,m,value[100005],whpath[100005],whpos[100005],x,y,nrfiisb[100005],tata[100005],nrpath,op,lev[100005];
int parent[100005],nrn[100005],sol;
int *laint[100005];
void dfs(int nod) {
lev[nod]=lev[tata[nod]]+1;
for (lista p=arb[nod]; p; p=p->next)
if (p->nod!=tata[nod]){ tata[p->nod]=nod; dfs(p->nod); }
int urm,mmax=0;
for (lista p=arb[nod]; p; p=p->next)
if (p->nod!=tata[nod]) {
nrfiisb[nod]+=nrfiisb[p->nod];
if (nrfiisb[p->nod]>mmax) { mmax=nrfiisb[p->nod]; urm=p->nod; }
}
nrfiisb[nod]+=1;
if (nrfiisb[nod]==1) {
++nrpath; whpath[nod]=nrpath; nrn[nrpath]=1;
v=new celula; v->nod=nod; v->next=aux[nrpath]; aux[nrpath]=v;
}
else {
v=new celula; v->nod=nod; v->next=aux[whpath[urm]]; aux[whpath[urm]]=v;
whpath[nod]=whpath[urm]; ++nrn[whpath[nod]];
for (lista p=arb[nod]; p; p=p->next)
if (p->nod!=tata[nod]&&p->nod!=urm) parent[whpath[p->nod]]=nod;
}
}
void update(int lant, int poz, int valoare, int nod, int l, int r){
if (l==r) laint[lant][nod]=valoare;
else {
int mid=(l+r)/2;
if (poz<=mid) update(lant,poz,valoare,2*nod,l,mid);
else update(lant,poz,valoare,2*nod+1,mid+1,r);
laint[lant][nod]=max(laint[lant][2*nod],laint[lant][2*nod+1]);
}
}
void querry(int lant, int x, int y, int nod, int l, int r) {
if (l>=x&&r<=y) sol=max(sol,laint[lant][nod]);
else {
int mid=(l+r)/2;
if (x<=mid) querry(lant,x,y,2*nod,l,mid);
if (y>mid) querry(lant,x,y,2*nod+1,mid+1,r);
}
}
void rezolva(int x, int y) {
if (whpath[x]==whpath[y]) querry(whpath[x],min(whpos[y],whpos[x]),max(whpos[y],whpos[x]),1,1,nrn[whpath[x]]);
else {
if (lev[parent[whpath[y]]]>lev[parent[whpath[x]]]) swap(x,y);
querry(whpath[x],1,whpos[x],1,1,nrn[whpath[x]]);
rezolva(parent[whpath[x]],y);
}
}
int main(void) {
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
fin>>n>>m;
for (i=1; i<=n; ++i) fin>>value[i];
for (i=1; i<n; ++i) {
fin>>x>>y;
v=new celula; v->nod=x; v->next=arb[y]; arb[y]=v;
v=new celula; v->nod=y; v->next=arb[x]; arb[x]=v;
}
dfs(1);
for (i=1; i<=nrpath; ++i) {
laint[i]=new int[4*nrn[i]];
int pas=0;
for (lista p=aux[i]; p; p=p->next) { ++pas; whpos[p->nod]=pas; update(i,pas,value[p->nod],1,1,nrn[i]); }
}
for (i=1; i<=m; ++i){
fin>>op>>x>>y;
if (op==0) update(whpath[x],whpos[x],y,1,1,nrn[whpath[x]]);
else {
sol=0;
rezolva(x,y);
fout<<sol<<"\n";
}
}
return(0);
}