#include <bits/stdc++.h>
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
int n,m,cost[100005],nr=0,aint[400005],niv[100005],sol;
int ctarb[100005],ltata[100005],lnivel[100005],lpoz[100005],nrdrumuri,diml[100005],loc[100005];
vector<int>G[100005],paths[100005];
void df(int nod,int tata,int height)
{
ctarb[nod]=1;
niv[nod]=height;
int fiumax=-1;
for(int i=0;i<G[nod].size();i++){
int x=G[nod][i];
if( x!=tata ){
df(x,nod,height+1);
ctarb[nod]+=ctarb[x];
if(ctarb[nod]==-1) fiumax=x;
else if(ctarb[fiumax]<ctarb[x]) fiumax=x;
}
}
if( fiumax==-1 ){
loc[nod]=++nrdrumuri;
diml[nrdrumuri]=1;
paths[nrdrumuri].push_back(nod);
return;
}
loc[nod]=loc[fiumax];
diml[loc[nod]]++;
paths[loc[nod]].push_back(nod);
for(int i=0;i<G[nod].size();i++){
int x=G[nod][i];
if( x!=fiumax&&x!=tata )
{
ltata[loc[x]]=nod;
lnivel[loc[x]]=height;
}
}
}
void build(int nod,int st,int dr,int decalaj,int lant)
{
if(st==dr){
aint[nod+decalaj] = cost[paths[lant][st-1]];
return;
}
int mid=(st+dr)/2;
build(nod*2,st,mid,decalaj,lant);
build(nod*2+1,mid+1,dr,decalaj,lant);
aint[nod+decalaj] = max( aint[nod*2+decalaj],aint[nod*2+1+decalaj] );
}
void uptade(int nod,int st,int dr,int decalaj,int poz,int val)
{
if( st==dr ){
aint[nod+decalaj] = val;
return;
}
int mid=(st+dr)/2;
if(poz<=mid) uptade(nod*2,st,mid,decalaj,poz,val);
else uptade(nod*2+1,mid+1,dr,decalaj,poz,val);
aint[nod+decalaj] = max( aint[nod*2+decalaj],aint[nod*2+1+decalaj] );
}
void query(int nod,int st,int dr,int a,int b,int decalaj)
{
if( a<=st&&dr<=b ){
sol=max(sol,aint[nod+decalaj]);
return;
}
int mid=(st+dr)/2;
if(a<=mid) query(nod*2,st,mid,a,b,decalaj);
if(mid<b) query(nod*2+1,mid+1,dr,a,b,decalaj);
}
void solve()
{
for(int i=1;i<=m;i++)
{
int op1,op2,tip;
f>>tip>>op1>>op2;
if(tip==0){
cost[op1]=op2;
uptade(1,1,diml[loc[op1]],lpoz[loc[op1]],niv[op1]-lnivel[loc[op1]],op2);
}
else
{
sol=0;
while(1)
{
if( loc[op1]==loc[op2] )
{
if( niv[op1]>niv[op2] )
swap(op1,op2);
query(1,1,diml[loc[op1]],niv[op1]-lnivel[loc[op1]],niv[op2]-lnivel[loc[op2]],lpoz[loc[op1]]);
break;
}
if( lnivel[loc[op1]]<lnivel[loc[op2]] )
swap(op1,op2);
query(1,1,diml[loc[op1]],1,niv[op1]-lnivel[loc[op1]],lpoz[loc[op1]]);
op1=ltata[loc[op1]];
}
g<<sol<<'\n';
}
}
}
int main()
{
f>>n>>m;
for(int i=1; i<=n; i++)
f>>cost[i];
for(int i=1; i<n; i++)
{
int x,y;
f>>x>>y;
G[x].push_back(y);
G[y].push_back(x);
}
df(1,0,1);
///creez drumurile
for(int i=1;i<=nrdrumuri;i++){
reverse(paths[i].begin(),paths[i].end());
if(i>1) lpoz[i]=lpoz[i-1]+4*diml[i-1];
build(1,1,diml[i],lpoz[i],i);
}
///
solve();
}