#include <stdio.h>
#include <vector>
#include <algorithm>
#define NMAX 100005
#define HMAX 400005
#define LMAX 505
#define pb push_back
using namespace std;
int n,m,V[NMAX],B[NMAX],best[NMAX],nr_chains,which[NMAX],where[NMAX],arb[HMAX],dad[LMAX];
int lvl[NMAX],dec[LMAX],father[NMAX],v1,v2,p1,p2,rez;
vector <int> A[NMAX],C[LMAX];
bool viz[NMAX];
void read()
{
scanf("%d%d",&n,&m);
int i,x,y;
for (i=1; i<=n; i++)
scanf("%d",&V[i]);
for (i=1; i<n; i++)
{
scanf("%d%d",&x,&y);
A[x].pb(y); A[y].pb(x);
}
}
void dfs(int nod)
{
viz[nod]=1; B[nod]=1;
int i,vec;
for (i=0; i<A[nod].size(); i++)
{
vec=A[nod][i];
if (!viz[vec])
{
father[vec]=nod; lvl[vec]=lvl[nod]+1;
dfs(vec);
B[nod]+=B[vec];
if (B[vec]>B[best[nod]])
best[nod]=vec;
}
}
if (B[nod]==1)
{
nr_chains++; which[nod]=nr_chains;
C[nr_chains].pb(nod);
return ;
}
C[which[best[nod]]].pb(nod); which[nod]=which[best[nod]];
for (i=0; i<A[nod].size(); i++)
{
vec=A[nod][i];
if (father[vec]==nod && vec!=best[nod])
dad[which[vec]]=nod;
}
}
inline int max(int x,int y)
{
return x>y ? x : y;
}
void cstr(int st,int dr,int nod,int decalaj,int ind)
{
if (st==dr)
{
arb[nod+decalaj]=V[C[ind][st-1]];
return ;
}
int mij=(st+dr)/2;
cstr(st,mij,nod*2,decalaj,ind);
cstr(mij+1,dr,nod*2+1,decalaj,ind);
arb[nod+decalaj]=max(arb[nod*2+decalaj],arb[nod*2+1+decalaj]);
}
void cons()
{
int i,j;
for (i=1; i<=nr_chains; i++)
reverse(C[i].begin(),C[i].end());
for (i=1; i<=nr_chains; i++)
{
for (j=0; j<C[i].size(); j++)
where[C[i][j]]=j+1;
dec[i]=dec[i-1]+4*C[i].size();
cstr(1,C[i].size(),1,dec[i-1],i);
}
}
void update(int st,int dr,int nod,int decalaj)
{
if (st==dr)
{
arb[nod+decalaj]=v2;
return ;
}
int mij=(st+dr)/2;
if (where[v1]<=mij)
update(st,mij,nod*2,decalaj);
else
update(mij+1,dr,nod*2+1,decalaj);
arb[nod+decalaj]=max(arb[nod*2+decalaj],arb[nod*2+1+decalaj]);
}
int search(int st,int dr,int nod,int decalaj)
{
if (p1<=st && dr<=p2)
return arb[nod+decalaj];
if (p2<st || dr<p1)
return 0;
int mij=(st+dr)/2;
return max(search(st,mij,nod*2,decalaj),search(mij+1,dr,nod*2+1,decalaj));
}
void solve()
{
int i,tip;
for (i=1; i<=m; i++)
{
scanf("%d%d%d",&tip,&v1,&v2);
if (tip==0)
update(1,C[which[v1]].size(),1,dec[which[v1]-1]);
if (tip==1)
{
rez=0;
while (which[v1]!=which[v2])
{
if (lvl[dad[which[v1]]]>lvl[dad[which[v2]]])
{
p1=1; p2=where[v1];
rez=max(rez,search(1,C[which[v1]].size(),1,dec[which[v1]-1]));
v1=dad[which[v1]];
}
else
{
p1=1; p2=where[v2];
rez=max(rez,search(1,C[which[v2]].size(),1,dec[which[v2]-1]));
v2=dad[which[v2]];
}
}
if (where[v1]>where[v2]) swap(v1,v2);
p1=where[v1]; p2=where[v2];
rez=max(rez,search(1,C[which[v1]].size(),1,dec[which[v1]-1]));
printf("%d\n",rez);
}
}
}
int main()
{
freopen("heavypath.in","r",stdin);
freopen("heavypath.out","w",stdout);
read();
dfs(1);
cons();
solve();
return 0;
}