#include <bits/stdc++.h>
#define dbg cout<<"OK"<<endl;
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
const int dim=100009;
vector<int>v[dim];
int sz[dim],parent[dim],depth[dim],val[dim];
struct SegmentTreeMaxim{
int aint[4*dim];
void update(int nod,int tl,int tr,int poz,int val){
if(tl==tr){
aint[nod]=val;
return;
}
int tm=(tl+tr)/2;
if(poz<=tm){
update(2*nod,tl,tm,poz,val);
}
else{
update(2*nod+1,tm+1,tr,poz,val);
}
aint[nod]=max(aint[2*nod],aint[2*nod+1]);
}
int query(int nod,int tl,int tr,int l,int r){
if(l==tl && r==tr){
return aint[nod];
}
int tm=(tl+tr)/2;
if(r<=tm){
return query(2*nod,tl,tm,l,r);
}
if(l>tm){
return query(2*nod+1,tm+1,tr,l,r);
}
return max(query(2*nod,tl,tm,l,tm),query(2*nod+1,tm+1,tr,tm+1,r));
}
}A;
void dfs_size(int x,int tata){
sz[x]=1;
depth[x]=depth[tata]+1;
for(int y:v[x]){
if(y!=tata){
dfs_size(y,x);
sz[x]+=sz[y];
parent[y]=x;
}
}
}
int nr_comp,comp[dim],poz_aint[dim];
vector<int>c[dim];///nodurile care fac parte din componenta i
void HPD(int x,bool schimba,int comp_tata){///generare lanturi HPD
int comp_locala;
if(schimba){
nr_comp++;
comp_locala=nr_comp;
}
else{
comp_locala=comp_tata;
}
c[comp_locala].push_back(x);
comp[x]=comp_locala;
for(int y:v[x]){
if(y!=parent[x]){
if(sz[y]>sz[x]/2){
HPD(y,0,comp_locala);
}
else{
HPD(y,1,comp_locala);
}
}
}
}
signed main(){
int n,q;
fin>>n>>q;
for(int i=1;i<=n;i++){
fin>>val[i];
}
for(int i=2;i<=n;i++){
int x,y;
fin>>x>>y;
v[x].push_back(y);
v[y].push_back(x);
}
dfs_size(1,0);
HPD(1,1,0);
int total=0;
for(int i=1;i<=nr_comp;i++){
for(int x:c[i]){
total++;
poz_aint[x]=total;
A.update(1,1,n,total,val[x]);
}
}
while(q--){
int op;
fin>>op;
if(op==0){
int poz,val;
fin>>poz>>val;
A.update(1,1,n,poz_aint[poz],val);
}
else{
int l,r;
fin>>l>>r;
int ans=0;
if(depth[l]<depth[r]){
swap(l,r);
}
while(c[comp[l]][0]!=c[comp[r]][0]){
ans=max(ans,A.query(1,1,total,poz_aint[c[comp[r]][0]],poz_aint[r]));
if(parent[c[comp[r]][0]])
r=parent[c[comp[r]][0]];
if(depth[c[comp[l]][0]]>depth[c[comp[r]][0]]){
swap(l,r);
}
}
if(depth[l]>depth[r]){
swap(l,r);
}
ans=max(ans,A.query(1,1,total,poz_aint[l],poz_aint[r]));
fout<<ans<<'\n';
}
}
}