#include <bits/stdc++.h>
#define NMAX 100005
#define pb push_back
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
bool viz[NMAX];
int sub[NMAX],whichpath[NMAX],dimpath[NMAX],pathdepth[NMAX],pathfather[NMAX];
int depth[NMAX],nrpaths,aint[4*NMAX],val[NMAX],pozpath[NMAX];
vector<int> G[NMAX],P[NMAX];
void DFS(int x) {
sub[x]=viz[x]=1;
int care=0;
sub[0]=-1;
for(auto it:G[x]) {
if(viz[it]) continue;
depth[it]=depth[x]+1;
DFS(it);
sub[x]+=sub[it];
if(sub[care]<sub[it]) care=it;
}
if(G[x].size()==1 && x!=1) {
P[++nrpaths].pb(x);
dimpath[nrpaths]=1;
whichpath[x]=nrpaths;
return;
}
whichpath[x]=whichpath[care];
dimpath[whichpath[x]]++;
P[whichpath[x]].pb(x);
for(auto it:G[x]) {
if(it==care || depth[it]<depth[x]) continue;
pathfather[whichpath[it]]=x;
pathdepth[whichpath[it]]=depth[x];
}
}
void build(int nod, int st, int dr, int decalaj, int path) {
if(st==dr) {
aint[nod+decalaj]=val[P[path][st-1]];
return;
}
int fs=nod*2,mid=(st+dr)/2;
build(fs,st,mid,decalaj,path);
build(fs+1,mid+1,dr,decalaj,path);
aint[nod+decalaj]=max(aint[fs+decalaj],aint[fs+decalaj+1]);
}
void update(int nod, int st, int dr, int poz, int val, int decalaj) {
if(st==dr) {
aint[nod+decalaj] = val;
return;
}
int fs=nod*2,mid=(st+dr)/2;
if(poz<=mid) update(fs,st,mid,poz,val,decalaj);
else update(fs+1,mid+1,dr,poz,val,decalaj);
aint[nod + decalaj]=max(aint[fs+decalaj],aint[fs+decalaj+1]);
}
int query(int nod, int st, int dr, int qst, int qdr, int decalaj) {
if(qst<=st && dr<=qdr)
return aint[nod+decalaj];
int fs=nod*2,mid=(st+dr)/2,res=0;
if(qst<=mid) res=max(res,query(fs,st,mid,qst,qdr,decalaj));
if(mid<qdr) res=max(res,query(fs+1,mid+1,dr,qst,qdr,decalaj));
return res;
}
int main() {
int n,i,t,x,y,m,ans;
fin>>n>>m;
for(i=1;i<=n;++i) fin>>val[i];
for(i=1;i<n;++i) {
fin>>x>>y;
G[x].pb(y);
G[y].pb(x);
}
depth[1]=1;
DFS(1);
for(i=1;i<=nrpaths;++i) {
reverse(P[i].begin(),P[i].end());
pozpath[i]=pozpath[i-1]+4*dimpath[i-1];
build(1,1,dimpath[i],pozpath[i],i);
}
for(i=1;i<=m;++i) {
fin>>t>>x>>y;
if(t==0)
update(1,1,dimpath[whichpath[x]],depth[x]-pathdepth[whichpath[x]],y,pozpath[whichpath[x]]);
else {
ans=0;
while(1) {
if(whichpath[x]==whichpath[y]) {
if(depth[x]>depth[y]) swap(x,y);
ans=max(ans,query(1,1,dimpath[whichpath[x]],depth[x]-pathdepth[whichpath[x]],depth[y]-pathdepth[whichpath[y]],pozpath[whichpath[x]]));
break;
}
if(pathdepth[whichpath[x]]<pathdepth[whichpath[y]]) swap(x,y);
ans=max(ans,query(1,1,dimpath[whichpath[x]],1,depth[x]-pathdepth[whichpath[x]],pozpath[whichpath[x]]));
x=pathfather[whichpath[x]];
}
fout<<ans<<'\n';
}
}
}