#include<fstream>
#include<vector>
#define NMAX 100100
using namespace std;
vector <int> G[NMAX],SirElem[NMAX];
int n,nr_sir;
int v[NMAX],aint[4*NMAX],poz[NMAX];
int nivel[NMAX],fii[NMAX],lant[NMAX],tata[NMAX];
bool viz[NMAX];
int query(int nod,int left,int right,int a,int b,int decalaj) {
if(a<=left&&right<=b)
return aint[nod+decalaj];
int mid=(left+right)>>1,rez=0;
if(a<=mid)
rez=query(2*nod,left,mid,a,b,decalaj);
if(b>mid)
rez=query(2*nod+1,mid+1,right,a,b,decalaj);
return rez;
}
void update(int nod,int left,int right,int poz,int decalaj,int val) {
if(left==right) {
aint[nod+decalaj]=val;
return;
}
int mid=(left+right)>>1;
if(poz<=mid)
update(2*nod,left,mid,poz,decalaj,val);
else
update(2*nod+1,mid+1,right,poz,decalaj,val);
aint[nod+decalaj]=max(aint[2*nod+decalaj],aint[2*nod+1+decalaj]);
}
void build(int nod,int left,int right,int decalaj,int lant) {
if(left==right) {
aint[nod+decalaj]=v[SirElem[lant][left-1]];
return;
}
int mid=(left+right)>>1;
build(2*nod,left,mid,decalaj,lant);
build(2*nod+1,mid+1,right,decalaj,lant);
aint[nod+decalaj]=max(aint[2*nod+decalaj],aint[2*nod+1+decalaj]);
}
void dfs(int nod) {
int i,vecin,best=-1;
viz[nod]=1;
fii[nod]=1;
for(i=0;i<G[nod].size();i++) {
vecin=G[nod][i];
if(viz[vecin])
continue;
nivel[vecin]=nivel[nod]+1;
dfs(vecin);
fii[nod]+=fii[vecin];
if(best==-1)
best=vecin;
else
if(fii[best]<fii[vecin])
best=vecin;
}
if(fii[nod]==1) {
lant[nod]=++nr_sir;
SirElem[nr_sir].push_back(nod);
return;
}
lant[nod]=lant[best];
SirElem[lant[best]].push_back(nod);
for(i=0;i<G[nod].size();i++)
if(G[nod][i]!=best)
tata[lant[G[nod][i]]]=nod;
}
void make_paths() {
int i;
nivel[1]=1;
dfs(1);
for(i=1;i<=nr_sir;i++) {
reverse(SirElem[i].begin(),SirElem[i].end());
poz[i]=poz[i-1]+SirElem[i-1].size()*4;
build(1,1,SirElem[i].size(),poz[i],i);
}
}
int main() {
int i,t,x,y,m,sol;
ifstream in("heavypath.in");
ofstream out("heavypath.out");
in>>n>>m;
for(i=1;i<=n;in>>v[i++]);
for(i=1;i<n;i++) {
in>>x>>y;
G[x].push_back(y);
G[y].push_back(x);
}
make_paths();
for(i=0;i<m;i++) {
in>>t>>x>>y;
if(t==0)
update(1,1,SirElem[lant[x]].size(),nivel[x]-nivel[tata[lant[x]]],poz[lant[x]],y);
else {
sol=1;
while( true ) {
if(lant[x]==lant[y]) {
if(nivel[x]>nivel[y])
swap(x,y);
sol=max(sol,query(1,1,SirElem[lant[x]].size(),nivel[x]-nivel[tata[lant[x]]],nivel[y]-nivel[tata[lant[y]]],poz[lant[x]]));
break;
}
if(nivel[tata[lant[x]]]<nivel[tata[lant[y]]])
swap(x,y);
sol=max(sol,query(1,1,SirElem[lant[x]].size(),1,nivel[x]-nivel[tata[lant[x]]],poz[lant[x]]));
x=tata[lant[x]];
}
out<<sol<<'\n';
}
}
in.close();
out.close();
return 0;
}