#include <fstream>
#include <vector>
#include <algorithm>
#define N 100011
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
struct lant
{
int dim,lvl,poz,tata;
vector <int> elem;
}l[N];
vector <int> arb[N];
bool fost[N];
int nrsub[N],lvl[N],L,a[N*4],lan[N],val[N];
void dfs(int k)
{
fost[k]=nrsub[k]=1;
bool frunza=1;
int F,M=0;
for(auto it=arb[k].begin();it!=arb[k].end();it++)
{
if(fost[*it]==1)
continue;
frunza=0;
lvl[*it]=lvl[k]+1;
dfs(*it);
nrsub[k]=nrsub[k]+nrsub[*it];
if(M<nrsub[*it])
{
F=*it;
M=nrsub[*it];
}
}
if(frunza==1)
{
L++;
lan[k]=L;
l[L].dim=1;
l[L].elem.push_back(k);
return;
}
lan[k]=lan[F];
l[lan[k]].dim++;
l[lan[k]].elem.push_back(k);
for(auto it=arb[k].begin();it!=arb[k].end();it++)
{
if(*it==F || lvl[*it]<lvl[k])
continue;
l[lan[*it]].tata=k;
l[lan[*it]].lvl=lvl[k];
}
}
void aint_build(int st,int dr,int decal,int k,int ind)
{
if(st==dr)
{
a[k+decal]=val[l[ind].elem[st-1]];
return;
}
int mij=(st+dr)/2;
aint_build(st,mij,decal,k*2,ind);
aint_build(mij+1,dr,decal,k*2+1,ind);
a[k+decal]=max(a[k*2+decal],a[k*2+1+decal]);
}
void lant_build()
{
lvl[1]=1;
dfs(1);
for(int i=1;i<=L;i++)
{
reverse(l[i].elem.begin(),l[i].elem.end());
if(i>1)
l[i].poz=l[i-1].poz+l[i-1].dim*4;
aint_build(1,l[i].dim,l[i].poz,1,i);
}
}
void update(int st,int dr,int poz,int decal,int val,int k)
{
if(st==dr)
{
a[k+decal]=val;
return;
}
int mij=(st+dr)/2;
if(poz<=mij)
update(st,mij,poz,decal,val,k*2);
else
update(mij+1,dr,poz,decal,val,k*2+1);
a[k+decal]=max(a[k*2+decal],a[k*2+1+decal]);
}
int query(int st,int dr,int x,int y,int decal,int k)
{
if(st>=x && dr<=y)
return a[k+decal];
int mij=(st+dr)/2,M=0;
if(x<=mij)
M=max(M,query(st,mij,x,y,decal,k*2));
if(y>mij)
M=max(M,query(mij+1,dr,x,y,decal,k*2+1));
return M;
}
int n,m,i,sol,x,y,C;
int main()
{
f>>n>>m;
for(i=1;i<=n;i++)
f>>val[i];
for(i=1;i<n;i++)
{
f>>x>>y;
arb[x].push_back(y);
arb[y].push_back(x);
}
lant_build();
for(i=1;i<=m;i++)
{
f>>C>>x>>y;
if(C==0)
update(1,l[lan[x]].dim,lvl[x]-l[lan[x]].lvl,l[lan[x]].poz,y,1);
else
{
sol=0;
while(1)
{
if(lan[x]==lan[y])
{
if(lvl[x]>lvl[y])
swap(x,y);
sol=max(sol,query(1,l[lan[x]].dim,lvl[x]-l[lan[x]].lvl,lvl[y]-l[lan[y]].lvl,l[lan[x]].poz,1));
break;
}
if(l[lan[x]].lvl<l[lan[y]].lvl)
swap(x,y);
sol=max(sol,query(1,l[lan[x]].dim,1,lvl[x]-l[lan[x]].lvl,l[lan[x]].poz,1));
x=l[lan[x]].tata;
}
g<<sol<<'\n';
}
}
return 0;
}