#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int nmax = 100005;
int n,m,val[nmax],i,x,y,subarb[nmax],lev[nmax],f[nmax],poz[nmax],lant[nmax],paths,Poz,Val,a,b,sol;
vector<int> v[nmax],p[nmax],arb[nmax];
void dfs(int x,int t)
{
subarb[x]=1;
for(vector<int>::iterator it=v[x].begin();it!=v[x].end();it++)
if(*it!=t)
{
f[*it]=x;
lev[*it]=lev[x]+1;
dfs(*it,x);
subarb[x]+=subarb[*it];
}
if(v[x].size()==1 && x!=1)
{
lant[x]=++paths;
p[paths].push_back(0);
p[paths].push_back(x);
poz[x]=1;
return;
}
int maxs=0;
for(vector<int>::iterator it=v[x].begin();it!=v[x].end();it++)
if(*it!=t && subarb[*it]>subarb[maxs]) maxs=*it;
lant[x]=lant[maxs];
p[lant[x]].push_back(x);
poz[x]=p[lant[x]].size()-1;
}
void build(int node,int l,int r,int path)
{
if(l==r) {arb[path][node]=val[p[path][l]]; return;}
int m=(l+r)/2;
int ls=2*node;
int rs=ls+1;
build(ls,l,m,path);
build(rs,m+1,r,path);
arb[path][node]=max(arb[path][ls],arb[path][rs]);
}
void update(int node,int l,int r,int path)
{
if(l==r) {arb[path][node]=Val; return;}
int m=(l+r)/2;
int ls=2*node;
int rs=ls+1;
if(Poz<=m) update(ls,l,m,path);
else update(rs,m+1,r,path);
arb[path][node]=max(arb[path][ls],arb[path][rs]);
}
void query(int node,int l,int r,int path)
{
if(l>=a && r<=b) {sol=max(sol,arb[path][node]); return;}
int m=(l+r)/2;
int ls=2*node;
int rs=ls+1;
if(a<=m) query(ls,l,m,path);
if(b>m) query(rs,m+1,r,path);
}
int main()
{
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);
v[x].push_back(y);
v[y].push_back(x);
}
lev[1]=1; dfs(1,0);
for(i=1;i<=paths;i++)
{
reverse(p[i].begin()+1,p[i].end());
arb[i].resize(4*p[i].size()+5);
build(1,1,p[i].size()-1,i);
}
for(i=1;i<=n;i++) poz[i]=p[lant[i]].size()-poz[i];
for(;m;m--)
{
scanf("%d%d%d",&i,&x,&y);
if(i==0)
{
Poz=poz[x]; Val=y;
update(1,1,p[lant[x]].size()-1,lant[x]);
}
else
{
sol=0;
for(;;)
{
if(lant[x]==lant[y])
{
a=min(poz[x],poz[y]);
b=max(poz[x],poz[y]);
query(1,1,p[lant[x]].size()-1,lant[x]);
break;
}
if(lev[p[lant[x]][1]]<lev[p[lant[y]][1]]) swap(x,y);
a=1; b=poz[x]; query(1,1,p[lant[x]].size()-1,lant[x]);
x=f[p[lant[x]][1]];
}
printf("%d\n",sol);
}
}
return 0;
}