#include<fstream>
#include<algorithm>
#define N 100005
using namespace std;
typedef struct celula {
int nod;
celula *next;
}*lista;
lista arb[N],aux[N/2],v;
int i,n,m,value[N],whpath[N],whpos[N],x,y,nrfiisb[N],nrpath,op,lev[N];
int parent[N/2],nrn[N/2],sol;
int *laint[N/2];
void dfs(int nod, int prec) {
lev[nod]=lev[prec]+1; lista p;
for (p=arb[nod]; p; p=p->next)
if (p->nod!=prec) dfs(p->nod,nod);
int urm=0,mmax=0;
for (p=arb[nod]; p; p=p->next)
if (p->nod!=prec) {
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 (p=arb[nod]; p; p=p->next)
if (p->nod!=prec&&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,0);
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);
}