#include <stdio.h>
#include <vector>
#include <algorithm>
#define NMAX 100005
#define LMAX (1<<19)
#define pb push_back
using namespace std;
int n,m,r,val[NMAX],nr[NMAX],fii[NMAX],dad[NMAX],lvl[NMAX],L[NMAX],which[NMAX],best[NMAX],nl,poz[NMAX],C[NMAX],D[NMAX],arb[LMAX],rez;
vector <int> A[NMAX],B[NMAX];
char viz[NMAX];
void read()
{
scanf("%d%d",&n,&m);
int i,a,b;
for (i=1; i<=n; i++)
scanf("%d",&val[i]);
for (i=1; i<n; i++)
{
scanf("%d%d",&a,&b);
A[a].pb(b);
A[b].pb(a);
}
}
void dfs(int nod)
{
viz[nod]=1;
nr[nod]=1;
int i,vec;
for (i=0; i<A[nod].size(); i++)
{
vec=A[nod][i];
if (!viz[vec])
{
lvl[vec]=lvl[nod]+1;
fii[nod]++;
dfs(vec);
nr[nod]+=nr[vec];
if (nr[vec]>nr[best[nod]])
best[nod]=vec;
}
}
if (!fii[nod])
{
nl++;
L[nl]=1; which[nod]=nl;
B[nl].pb(nod);
return ;
}
L[which[best[nod]]]++;
B[which[best[nod]]].pb(nod);
which[nod]=which[best[nod]];
for (i=0; i<A[nod].size(); i++)
{
vec=A[nod][i];
if (vec!=best[nod] && lvl[vec]>lvl[nod])
dad[which[vec]]=nod;
}
}
void cstr(int st,int dr,int nod,int decalaj,int act)
{
if (st==dr)
{
arb[nod+decalaj]=val[B[act][st-1]];
return ;
}
int mij=(st+dr)/2;
cstr(st,mij,nod*2,decalaj,act);
cstr(mij+1,dr,nod*2+1,decalaj,act);
arb[nod+decalaj]=max(arb[nod*2+decalaj],arb[nod*2+1+decalaj]);
}
void chains()
{
dfs(1);
int i,j,nod;
for (i=1; i<=nl; i++)
reverse(B[i].begin(),B[i].end());
for (i=1; i<=nl; i++)
{
if (i>1)
D[i]=D[i-1]+4*B[i-1].size();
else
D[i]=0;
cstr(1,L[i],1,D[i],i);
for (j=0; j<B[i].size(); j++)
{
nod=B[i][j];
C[++r]=nod;
poz[nod]=j+1;
}
}
}
inline int max(int x,int y)
{
return x>y ? x : y;
}
void update(int st,int dr,int nod,int position,int value,int decalaj)
{
if (st==dr)
{
arb[nod+decalaj]=value;
return ;
}
int mij=(st+dr)/2;
if (position<=mij)
update(st,mij,nod*2,position,value,decalaj);
else
update(mij+1,dr,nod*2+1,position,value,decalaj);
arb[nod+decalaj]=max(arb[nod*2+decalaj],arb[nod*2+1+decalaj]);
}
int query(int st,int dr,int nod,int a,int b,int decalaj)
{
if (b<st || a>dr)
return 0;
if (a<=st && dr<=b)
return arb[nod+decalaj];
int mij=(st+dr)/2;
return max(query(st,mij,nod*2,a,b,decalaj),query(mij+1,dr,nod*2+1,a,b,decalaj));
}
void solve()
{
int i,tip,x,y;
lvl[0]=-1;
for (i=1; i<=m; i++)
{
scanf("%d%d%d",&tip,&x,&y);
if (tip==0)
update(1,L[which[x]],1,poz[x],y,D[which[x]]);
else
{
rez=0;
while (which[x]!=which[y])
{
if (lvl[dad[which[x]]]<lvl[dad[which[y]]])
swap(x,y);
rez=max(rez,query(1,L[which[x]],1,1,poz[x],D[which[x]]));
x=dad[which[x]];
}
if (poz[x]>poz[y])
swap(x,y);
rez=max(rez,query(1,L[which[x]],1,poz[x],poz[y],D[which[x]]));
printf("%d\n",rez);
}
}
}
int main()
{
freopen("heavypath.in","r",stdin);
freopen("heavypath.out","w",stdout);
read();
chains();
solve();
return 0;
}