#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
vector<int> v[100010],arb[100010];
int val[100010],sizesubarb[100010],niv[100010],lant[100010],poz[100010],sizelant[100010],firstnod[100010],tata[100010];
int nrlant,poz1,val1,lant1,left,right,sol;
char vaz[100010];
void dfs1(int nod)
{
vaz[nod]=sizesubarb[nod]=1;
for(vector<int>::iterator it=v[nod].begin();it!=v[nod].end();it++)
if(!vaz[*it])
{
niv[*it]=niv[nod]+1;
dfs1(*it);
sizesubarb[nod]+=sizesubarb[*it];
}
}
void dfs2(int nod,int l)
{
vaz[nod]=1;
lant[nod]=l;
poz[nod]=++sizelant[l];
int maxsubarb=0,heavyfiu=0;
for(vector<int>::iterator it=v[nod].begin();it!=v[nod].end();it++)
if(!vaz[*it] && sizesubarb[*it]>maxsubarb)
{
maxsubarb=sizesubarb[*it];
heavyfiu=*it;
}
if(heavyfiu) dfs2(heavyfiu,l);
for(vector<int>::iterator it=v[nod].begin();it!=v[nod].end();it++)
if(!vaz[*it])
{
nrlant++;
firstnod[nrlant]=*it;
tata[nrlant]=nod;
dfs2(*it,nrlant);
}
}
void update(int nod,int st,int dr)
{
if(st==dr)
{
arb[lant1][nod]=val1;
return;
}
if(poz1<=(st+dr)/2) update(nod*2,st,(st+dr)/2);
else update(nod*2+1,(st+dr)/2+1,dr);
arb[lant1][nod]=max(arb[lant1][nod*2],arb[lant1][nod*2+1]);
}
void query(int nod,int st,int dr)
{
if(left<=st && dr<=right)
{
sol=max(sol,arb[lant1][nod]);
return;
}
if(left<=(st+dr)/2) query(nod*2,st,(st+dr)/2);
if((st+dr)/2+1<=right) query(nod*2+1,(st+dr)/2+1,dr);
}
int main()
{
freopen("heavypath.in", "r", stdin);
freopen("heavypath.out", "w", stdout);
int n,m,x,y,t;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&val[i]);
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
dfs1(1);
memset(vaz,0,sizeof(vaz));
++nrlant;
firstnod[nrlant]=1;
dfs2(1,nrlant);
for(int i=1;i<=nrlant;i++) arb[i].resize(4*sizelant[i]);
for(int i=1;i<=n;i++)
{
poz1=poz[i];
val1=val[i];
lant1=lant[i];
update(1,1,sizelant[lant1]);
}
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&t,&x,&y);
if(!t)
{
poz1=poz[x];
val1=y;
lant1=lant[x];
update(1,1,sizelant[lant1]);
}
else
{
int rez=0;
while(lant[x]!=lant[y])
{
if(niv[firstnod[lant[x]]]<niv[firstnod[lant[y]]]) swap(x,y);
sol=0;lant1=lant[x];left=1;right=poz[x];
query(1,1,sizelant[lant1]);
rez=max(rez,sol);
x=tata[lant[x]];
}
left=poz[x];right=poz[y];lant1=lant[x];sol=0;
if(left>right) swap(left,right);
query(1,1,sizelant[lant1]);
rez=max(rez,sol);
printf("%d\n",rez);
}
}
return 0;
}