#include<algorithm>
#include<cstdio>
#include<vector>
#define NMax 100010
using namespace std;
int val[NMax],niv[NMax],SubArb[NMax];
int nrL,N,lantTata[NMax],lantNiv[NMax];
int arbInt[4*NMax],arbPoz[NMax];
int lantDim[NMax],lant[NMax];
vector<int> Vc[NMax],L[NMax];
void DF (int nod)
{
int bestFiu=-1,okFr=1;
SubArb[nod]=1;
vector<int>::iterator it;
for (it=Vc[nod].begin(); it!=Vc[nod].end(); ++it)
if (!niv[*it])
{
niv[*it]=niv[nod]+1;
okFr=0;
DF(*it);
SubArb[nod]+=SubArb[*it];
if (bestFiu==-1)
bestFiu=*it;
else if (SubArb[*it]>SubArb[bestFiu])
bestFiu=*it;
}
if (okFr)
{
lant[nod]=++nrL;
lantDim[nrL]=1;
L[nrL].push_back(nod);
}
else
{
lant[nod]=lant[bestFiu];
lantDim[lant[nod]]++;
L[lant[nod]].push_back(nod);
for (it=Vc[nod].begin(); it!=Vc[nod].end(); ++it)
if ((*it)!=bestFiu && niv[*it]>niv[nod])
{
lantTata[lant[*it]]=nod;
lantNiv[lant[*it]]=niv[nod];
}
}
}
void build (int nod, int st, int dr, int decj, int lant)
{
if (st==dr)
{
arbInt[nod+decj]=val[L[lant][st-1]];
return;
}
int mid=(st+dr)/2;
build(2*nod,st,mid,decj,lant);
build(2*nod+1,mid+1,dr,decj,lant);
arbInt[nod+decj]=max(arbInt[2*nod+decj],arbInt[2*nod+1+decj]);
}
void update (int nod, int st, int dr, int poz, int val, int decj)
{
if (st==dr)
{
arbInt[nod+decj]=val;
return;
}
int mid=(st+dr)/2;
if (poz<=mid)
update(2*nod,st,mid,poz,val,decj);
else
update(2*nod+1,mid+1,dr,poz,val,decj);
arbInt[nod+decj]=max(arbInt[2*nod+decj],arbInt[2*nod+1+decj]);
}
int query (int nod, int st, int dr, int a, int b, int decj)
{
if (a<=st && dr<=b)
return arbInt[nod+decj];
int mid=(st+dr)/2,rez=0;
if (a<=mid)
rez=max(rez,query(2*nod,st,mid,a,b,decj));
if (mid<b)
rez=max(rez,query(2*nod+1,mid+1,dr,a,b,decj));
return rez;
}
int main ()
{
int i,tip,x,y,M,sol;
freopen("heavypath.in","r",stdin);
freopen("heavypath.out","w",stdout);
scanf("%d%d",&N,&M);
for (i=1; i<=N; i++)
scanf("%d",&val[i]);
for (i=1; i<N; i++)
{
scanf("%d%d",&x,&y);
Vc[x].push_back(y);
Vc[y].push_back(x);
}
niv[1]=1;
DF(1);
for (i=1; i<=nrL; i++)
{
reverse(L[i].begin(),L[i].end());
arbPoz[i]=arbPoz[i-1]+4*lantDim[i-1];
build(1,1,lantDim[i],arbPoz[i],i);
}
for (i=1; i<=M; i++)
{
scanf("%d%d%d",&tip,&x,&y);
if (!tip)
update(1,1,lantDim[x],niv[x]-lantNiv[lant[x]],y,arbPoz[lant[x]]);
else
{
sol=0;
while (1)
{
if (lant[x]==lant[y])
{
if (niv[x]>niv[y])
swap(x,y);
sol=max(sol,query(1,1,lantDim[lant[x]],niv[x]-lantNiv[lant[x]],
niv[y]-lantNiv[lant[x]],arbPoz[lant[x]]));
break;
}
if (lantNiv[lant[x]]<lantNiv[lant[y]])
swap(x,y);
sol=max(sol,query(1,1,lantDim[lant[x]],1,niv[x]-lantNiv[lant[x]],arbPoz[lant[x]]));
x=lantTata[lant[x]];
}
printf("%d\n",sol);
}
}
return 0;
}