#include <cstdio>
#include <cstdlib>
FILE* in=fopen("heavypath.in","r");
FILE* out=fopen("heavypath.out","w");
const int Q=100007;
int val[2*Q],nxt[2*Q],lst[Q],nr;
struct Nod;
int n,q;
int max(const int &a, const int &b)
{
return a>b?a:b;
}
int ai[10*Q];
int lastloc=0;
struct arbore
{
// int *ai;
int dim;
int cst;
arbore(int dimensiune)
{
// ai=(int*) malloc(2*dimensiune+50);
// ai=new int[2*dimensiune+50];
dim=dimensiune;
cst=lastloc;
lastloc+=2*dim+50;
}
void update(int p, int st, int dr, int poz, int val)
{
if(st==dr)
{
ai[cst+p]=val;
return;
}
int md=(st+dr)/2;
if(poz<=md)
update(p*2,st,md,poz,val);
else
update(p*2+1,md+1,dr,poz,val);
ai[cst+p]=max(ai[cst+p*2],ai[cst+p*2+1]);
}
int query(int p, int st, int dr, int a, int b)
{
if(b<st || a>dr)
return 0;
if(a<=st && b>=dr)
return ai[cst+p];
return max(query(p*2,st,(st+dr)/2,a,b), query(p*2+1,(st+dr)/2+1,dr,a,b));
}
};
struct Lant
{
int lengh;
Nod *varf;
arbore *arb;
void finise()
{
if(arb==NULL)
arb=new arbore(lengh);
}
void update(int poz, int val)
{
arb->update(1,1,lengh,poz,val);
}
int query(int st, int dr)
{
return arb->query(1,1,lengh,st,dr);
}
} l[Q];
struct Nod
{
int h;
int c;
int fii;
Lant *lant;
Nod *tata;
} v[Q];
int last_lant=1;
void main2()
{
int t,x,y;
for(int i=1; i<=q; i++)
{
fscanf(in,"%d%d%d",&t,&x,&y);
if(t==0)
{
// l[v[x].lant].update(v[x].h-v[l[v[x].lant].varf].h+1,y);
v[x].lant->update(v[x].h-v[x].lant->varf->h+1,y);
}
else
{
int act=0;
Nod *a,*b;
a=&v[x];
b=&v[y];
while(a->lant!=b->lant)
{
if(a->lant->varf->tata->h > b->lant->varf->tata->h)
{
act=max(act,a->lant->query(1,a->h - a->lant->varf->h +1 ));
a=a->lant->varf->tata;
}
else
{
act=max(act,b->lant->query(1,b->h - b->lant->varf->h+1));
b=b->lant->varf->tata;
}
}
if(a->h > b->h )
act=max(act,a->lant->query(b->h- b->lant->varf->h+1,a->h - a->lant->varf->h+1));
else
act=max(act,a->lant->query(a->h - a->lant->varf->h+1,b->h- b->lant->varf->h+1));
fprintf(out,"%d\n",act);
}
}
}
void gen_lant(int nod, int lant)
{
if(nod==29800)
nod=29800;
if(l[lant].lengh==0)
{
l[lant].varf=&v[nod];
}
l[lant].lengh++;
v[nod].lant=&l[lant];
int who=0;
for(int p=lst[nod]; p; p=nxt[p])
{
if(v[val[p]].lant==0)
{
if(v[val[p]].fii>v[who].fii)
who=val[p];
}
}
for(int p=lst[nod]; p; p=nxt[p])
{
if(v[val[p]].lant==0)
{
if(val[p]==who)
{
gen_lant(val[p],lant);
}
else
{
gen_lant(val[p],++last_lant);
}
}
}
/*
if(nxt[lst[nod]]==0)
{
if(lant==3414)
lant=3414;
l[lant].finise();
}
*/
}
void nrfii(int nod, int tat)
{
v[nod].fii=1;
v[nod].tata=&v[tat];
for(int p=lst[nod]; p; p=nxt[p])
{
if(val[p]!=tat)
{
v[val[p]].h=v[nod].h+1;
nrfii(val[p],nod);
v[nod].fii+=v[val[p]].fii;
}
}
}
void add(int a, int b)
{
val[++nr]=b;
nxt[nr]=lst[a];
lst[a]=nr;
}
int main()
{
fscanf(in,"%d%d",&n,&q);
for(int i=1; i<=n; i++)
{
fscanf(in,"%d",&v[i].c);
}
int a,b;
for(int i=1; i<n; i++)
{
fscanf(in,"%d%d",&a,&b);
add(a,b);
add(b,a);
}
v[1].h=1;
nrfii(1,0);
gen_lant(1,1);
for(int i=1; i<=last_lant; i++)
l[i].finise();
for(int i=1; i<=n; i++)
{
// l[v[i].lant].update(v[i].h-v[l[v[i].lant].varf].h+1,v[i].c);
v[i].lant->update(v[i].h- v[i].lant->varf->h+1,v[i].c);
}
main2();
return 0;
}