#include <bits/stdc++.h>
#define maxN 100005
using namespace std;
int nrpaths;
int n,q,i,j,op,x,y,val[maxN];
int lvl[maxN],tata[maxN],weight[maxN];
int dim[maxN],pos[maxN],path[maxN];
vector<int> v[maxN],p[maxN],arb[maxN];
void build(int idx,int nod,int st,int dr)
{
if(st==dr){
arb[idx][nod]=val[p[idx][st-1]];
return;
}
int mij=st+(dr-st)/2;
build(idx,2*nod,st,mij);
build(idx,2*nod+1,mij+1,dr);
arb[idx][nod]=max(arb[idx][2*nod],arb[idx][2*nod+1]);
}
void update(int idx,int nod,int st,int dr,int poz,int value)
{
if(st==dr){
arb[idx][nod]=value;
return;
}
int mij=st+(dr-st)/2;
if(poz<=mij)
update(idx,2*nod,st,mij,poz,value);
else update(idx,2*nod+1,mij+1,dr,poz,value);
arb[idx][nod]=max(arb[idx][2*nod],arb[idx][2*nod+1]);
}
int query(int idx,int nod,int st,int dr,int start,int stop)
{
if(start<=st && dr<=stop)
return arb[idx][nod];
int mij=st+(dr-st)/2;
int res1=-0x3f3f3f3f;
int res2=-0x3f3f3f3f;
if(start<=mij)
res1=query(idx,2*nod,st,mij,start,stop);
if(mij<stop)
res2=query(idx,2*nod+1,mij+1,dr,start,stop);
return max(res1,res2);
}
void dfs(int nod)
{
bool leaf=true;
int maxx=0;
weight[nod]=1;
for(auto it:v[nod])
if(it!=tata[nod])
{
leaf=false;
lvl[it]=lvl[nod]+1;
tata[it]=nod;
dfs(it);
weight[nod]+=weight[it];
if(weight[maxx]<weight[it])
maxx=it;
}
if(leaf){
nrpaths++;
p[nrpaths].push_back(nod);
path[nod]=nrpaths;
dim[nrpaths]=1;
return;
}
p[path[maxx]].push_back(nod);
path[nod]=path[maxx];
dim[path[nod]]++;
}
void build_paths()
{
for(i=1;i<=nrpaths;i++)
{
reverse(p[i].begin(),p[i].end());
arb[i].resize(4*dim[i]+1);
for(j=0;j<dim[i];j++)
pos[p[i][j]]=j+1;
build(i,1,1,dim[i]);
}
}
int solvequery(int a,int b)
{
int l1,l2;
int t1,t2,x,y;
int res=0;
x=a,y=b;
t1=p[path[x]][0];
t2=p[path[y]][0];
while(path[x]!=path[y])
{
if(lvl[t1]<lvl[t2])
swap(x,y),swap(t1,t2);
int aux=query(path[x],1,1,dim[path[x]],1,pos[x]);
res=max(res,aux);
x=tata[t1];
t1=p[path[x]][0];
t2=p[path[y]][0];
}
int lim1=min(pos[x],pos[y]);
int lim2=max(pos[x],pos[y]);
int aux=query(path[x],1,1,dim[path[x]],lim1,lim2);
res=max(res,aux);
return res;
}
int main()
{
freopen("heavypath.in","r",stdin);
freopen("heavypath.out","w",stdout);
scanf("%d %d",&n,&q);
for(i=1;i<=n;i++)
scanf("%d",&val[i]);
for(i=1;i<n;i++){
scanf("%d %d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
lvl[1]=1;
dfs(1);
build_paths();
while(q--)
{
scanf("%d %d %d",&op,&x,&y);
if(op==0){
val[x]=y;
update(path[x],1,1,dim[path[x]],pos[x],val[x]);
}
else printf("%d\n",solvequery(x,y));
}
return 0;
}