#include <bits/stdc++.h>
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
int n,test,i,ans,val[100010],tata[100010],weight[100010],bestweight[100010],pos[100010],path[100010],cnt,aint[400010];
vector<int> edges[100010];
void dfs(int poz,int t)
{
tata[poz]=t;
weight[poz]=1;
for(auto it:edges[poz])
if(it!=t)
{
dfs(it,poz);
weight[poz]+=weight[it];
if(weight[it]>weight[bestweight[poz]])
bestweight[poz]=it;
}
return ;
}
void heavydfs(int poz,int dad)
{
pos[poz]=++cnt;
path[poz]=dad;
if(bestweight[poz])
{
heavydfs(bestweight[poz],dad);
for(auto it:edges[poz])
if(it!=tata[poz]&&it!=bestweight[poz])
heavydfs(it,it);
}
return ;
}
void upd(int poz,int l,int r,int wher,int vall)
{
if(l==r)
{
aint[poz]=vall;
return ;
}
int mi=(l+r)/2;
if(wher<=mi)
upd(poz*2 ,l ,mi,wher,vall);
else
upd(poz*2+1,mi+1,r ,wher,vall);
aint[poz]=max(aint[poz*2],aint[poz*2+1]);
return ;
}
void query(int poz,int l,int r,int lo,int hi)
{
if(lo<=l&&r<=hi)
{
ans=max(ans,aint[poz]);
return ;
}
int mi=(l+r)/2;
if(lo<=mi)
query(poz*2 ,l ,mi,lo,hi);
if(mi+1<=hi)
query(poz*2+1,mi+1,r ,lo,hi);
return;
}
int main()
{
f>>n>>test;
for(i=1; i<=n; i++)
f>>val[i];
for(i=1; i<n; i++)
{
int x,y;
f>>x>>y;
edges[x].push_back(y);
edges[y].push_back(x);
}
dfs(1,0);
heavydfs(1,1);
for(i=1;i<=n;i++)
upd(1,1,n,pos[i],val[i]);
for(;test;test--)
{
int t,x,y;
f>>t>>x>>y;
if(!t)
upd(1,1,n,pos[x],y);
else
{
ans=0;
while(path[x]!=path[y])
if(pos[x]>pos[y])
{
query(1,1,n,pos[path[x]],pos[x]);
x=tata[path[x]];
}
else
{
query(1,1,n,pos[path[y]],pos[y]);
y=tata[path[y]];
}
query(1,1,n,min(pos[x],pos[y]),max(pos[x],pos[y]));
g<<ans<<'\n';
}
}
return 0;
}