#include<bits/stdc++.h>
#define maxN 100005
using namespace std;
bool seen[maxN];
int pos[maxN];
int T[maxN],dp[maxN],niv[maxN];
int chaintop[maxN],where[maxN];
int A[4*maxN+5],fat[maxN],cnt;
vector<int> chain[maxN],v[maxN];
inline void dfs(int nod)
{
seen[nod]=1;
dp[nod]=1;
int best=0;
for(auto it:v[nod])
{
if(seen[it]) continue;
niv[it]=1+niv[nod];
dfs(it);
fat[it]=nod;
dp[nod]+=dp[it];
if(dp[it]>dp[best]) best=it;
}
if(dp[nod]==1)
{
cnt++;
chain[cnt].push_back(nod);
chaintop[cnt]=nod;
where[nod]=cnt;
}
else
{
int ch=where[best];
chain[ch].push_back(nod);
chaintop[ch]=nod;
where[nod]=ch;
}
}
inline void Update(int nod,int st,int dr,int val,int pos,int decalaj)
{
if(st==dr)
{
A[nod+decalaj]=val;
return;
}
else
{
int mid=(st+dr)>>1;
if(pos<=mid) Update(2*nod,st,mid,val,pos,decalaj);
else Update(2*nod+1,mid+1,dr,val,pos,decalaj);
A[nod+decalaj]=max(A[2*nod+decalaj],A[2*nod+decalaj+1]);
}
}
int sol;
inline void Query(int nod,int st,int dr,int a,int b,int decalaj)
{
if(a<=st && dr<=b)
{
sol=max(sol,A[nod+decalaj]);
return;
}
else
{
int mid=(st+dr)>>1;
if(a<=mid) Query(2*nod,st,mid,a,b,decalaj);
if(b>mid) Query(2*nod+1,mid+1,dr,a,b,decalaj);
}
}
int n,q,val[maxN],x,y,sp[maxN];
int main()
{
freopen("heavypath.in","r",stdin);
freopen("heavypath.out","w",stdout);
scanf("%d%d",&n,&q);
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);
}
dfs(1);
for(int i=1;i<=cnt;i++)
T[i]=fat[chaintop[i]];
for(int i=1;i<=cnt;i++)
{
for(int j=0;j<chain[i].size();j++)
pos[chain[i][j]]=j;
}
//dec=0;
for(int i=2;i<=cnt;i++)
{
sp[i]=sp[i-1]+4*chain[i-1].size();
}
int decal=0;
for(int i=1;i<=cnt;i++)
{
for(int j=0;j<chain[i].size();j++)
Update(1,0,chain[i].size()-1,val[chain[i][j]],j,decal);
decal+=4*chain[i].size();
}
int op,ch,ch1,ch2;
for(int i=1;i<=q;i++)
{
scanf("%d%d%d",&op,&x,&y);
if(!op)
{
val[x]=y;
ch=where[x];
Update(1,0,chain[ch].size()-1,val[x],pos[x],sp[ch]);
}
else
{
sol=0;
do
{
ch1=where[x];
ch2=where[y];
if(ch1==ch2)
{
if(pos[x]>pos[y]) swap(x,y);
Query(1,0,chain[ch1].size()-1,pos[x],pos[y],sp[ch1]);
break;
}
else
{
if(niv[T[ch1]]>niv[T[ch2]])
{
Query(1,0,chain[ch1].size()-1,pos[x],chain[ch1].size()-1,sp[ch1]);
x=T[ch1];
}
else
{
Query(1,0,chain[ch2].size()-1,pos[y],chain[ch2].size()-1,sp[ch2]);
y=T[ch2];
}
}
}while(1);
printf("%d\n",sol);
}
}
return 0;
}