#include <bits/stdc++.h>
using namespace std;
const int NMAX=1e5+5;
vector<int> edg[NMAX];
vector<int> path[NMAX];
vector<int> segtree[NMAX];
int p[NMAX],depth[NMAX],subtreeSize[NMAX],path_id[NMAX],pos[NMAX];
int current_path;
int cost[NMAX];
void dfs(int node){
subtreeSize[node]=1;
int bestChild=-1,maxSubtree=0;
for(auto it : edg[node]){
if(it!=p[node]){
p[it]=node,depth[it]=depth[node]+1;
dfs(it);
subtreeSize[node]+=subtreeSize[it];
if(subtreeSize[it]>maxSubtree)
maxSubtree=subtreeSize[it],bestChild=it;
}
}
if(bestChild==-1)
path_id[node]=current_path++;
else
path_id[node]=path_id[bestChild];
pos[node]=path[path_id[node]].size();
path[path_id[node]].push_back(node);
}
void Update(int id, int pathid, int val, int node, int l, int r){
if(id<l || id>r) return;
if(id==l && id==r){
segtree[pathid][node]=val;
}
else{
Update(id,pathid,val,node*2+1,l,(l+r)/2);
Update(id,pathid,val,node*2+2,(l+r)/2+1,r);
segtree[pathid][node]=max(segtree[pathid][node*2+1],segtree[pathid][node*2+2]);
}
}
int Query(int ql, int qr, int pathid, int node, int l, int r){
if(ql>r || qr<l) return 0;
if(ql<=l && r<=qr) return segtree[pathid][node];
return max(Query(ql,qr,pathid,node*2+1,l,(l+r)/2),Query(ql,qr,pathid,node*2+2,(l+r)/2+1,r));
}
int nxt_p2(int x){
int p2=1;
while(p2<x) p2<<=1;
return p2;
}
int main()
{
FILE* fin=fopen("heavypath.in","r");
FILE* fout=fopen("heavypath.out","w");
int n,q;
fscanf(fin,"%d%d",&n,&q);
for(int i=1;i<=n;i++)
fscanf(fin,"%d",&cost[i]);
for(int i=1;i<n;i++){
int u,v;
fscanf(fin,"%d%d",&u,&v);
edg[u].push_back(v);
edg[v].push_back(u);
}
dfs(1);
for(int i=0;i<current_path;i++){
segtree[i].resize(nxt_p2(path[i].size())*2);
}
for(int i=1;i<=n;i++){
Update(pos[i],path_id[i],cost[i],0,0,path[path_id[i]].size()-1);
/*for(auto it : segtree[path_id[i]])
cerr<<it<<' ';
cerr<<'\n';*/
}
while(q--){
int t,u,v;
fscanf(fin,"%d%d%d",&t,&u,&v);
if(t==0)
Update(pos[u],path_id[u],cost[u]=v,0,0,path[path_id[u]].size()-1);
else{
int ans=0;
while(path_id[u]!=path_id[v]){
if(depth[path[path_id[u]].back()]>depth[path[path_id[v]].back()]){
ans=max(ans,Query(pos[u],path[path_id[u]].size()-1,path_id[u],0,0,path[path_id[u]].size()-1));
u=p[path[path_id[u]].back()];
}
else{
ans=max(ans,Query(pos[v],path[path_id[v]].size()-1,path_id[v],0,0,path[path_id[v]].size()-1));
v=p[path[path_id[v]].back()];
}
}
if(depth[u]<depth[v]) u^=v,v^=u,u^=v;
fprintf(fout,"%d\n",max(ans,Query(pos[u],pos[v],path_id[u],0,0,path[path_id[u]].size()-1)));
}
}
return 0;
}