#include <stdio.h>
#include <vector>
#include <algorithm>
#define NMAX 100005
#define HMAX 400005
#define pb push_back
using namespace std;
int n,m,V[NMAX],C[NMAX],best[NMAX],chains,which[NMAX],where[NMAX],lvl[NMAX];
int father[NMAX],dad[NMAX],dec[NMAX],arb[HMAX],v1,v2,p1,p2,rez;
vector <int> A[NMAX],B[NMAX];
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; C[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);
C[nod]+=C[vec];
if (C[vec]>C[best[nod]])
best[nod]=vec;
}
}
if (C[nod]==1)
{
B[++chains].pb(nod); which[nod]=chains;
return ;
}
B[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[B[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 prepare()
{
int i,j;
for (i=1; i<=chains; i++)
reverse(B[i].begin(),B[i].end());
for (i=1; i<=chains; i++)
{
for (j=0; j<B[i].size(); j++)
where[B[i][j]]=j+1;
dec[i]=dec[i-1]+4*B[i].size();
cstr(1,B[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 (p1<=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 (p2<st || dr<p1)
return 0;
if (p1<=st && dr<=p2)
return arb[nod+decalaj];
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;
lvl[0]=-1;
for (i=1; i<=m; i++)
{
scanf("%d%d%d",&tip,&v1,&v2);
if (tip==0)
{
p1=where[v1];
update(1,B[which[v1]].size(),1,dec[which[v1]-1]);
}
else
{
rez=0;
while (which[v1]!=which[v2])
{
if (lvl[ dad[which[v1]] ] < lvl[ dad[which[v2]] ])
swap(v1,v2);
p1=1; p2=where[v1];
rez=max(rez,search(1,B[which[v1]].size(),1,dec[which[v1]-1]));
v1=dad[which[v1]];
}
if (where[v1]>where[v2])
swap(v1,v2);
p1=where[v1]; p2=where[v2];
rez=max(rez,search(1,B[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);
prepare();
solve();
return 0;
}