#include<fstream>
#include<iostream>
#include<vector>
#include<algorithm>
#define DN 100005
#define pb push_back
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
int n,m,r[4*DN],a[DN],p,q,niv[DN],nr,l[DN],c[DN],dim[DN],pr[DN];
int d[DN],val,poz,f,type,s,ma,nrq;
vector<int>v[DN];
vector<int>k[DN];
void dfs(int nod)
{
int vf=1,ma=-1,h;
for(auto i:v[nod])
if(niv[i]==0)
{
vf=0;
niv[i]=niv[nod]+1;
c[i]=1;
dfs(i);
c[nod]+=c[i];
if(c[i]>ma)
{
ma=c[i];
h=i;
}
}
if(vf)
{
nr++;
l[nod]=nr;
dim[nr]=1;
k[nr].pb(nod);
return;
}
dim[l[h]]++;
l[nod]=l[h];
k[l[h]].pb(nod);
for(auto i:v[nod])
if(niv[i]>niv[nod]&&i!=h)
pr[l[i]]=nod;
}
void update(int nod,int st,int dr,int decalaj)
{
if(st==dr)
{
r[nod+decalaj]=val;
return;
}
int mij=(st+dr)/2;
if(poz<=mij)
update(2*nod,st,mij,decalaj);
else
update(2*nod+1,mij+1,dr,decalaj);
r[nod+decalaj]=max(r[2*nod+decalaj],r[2*nod+1+decalaj]);
}
void query(int nod,int st,int dr,int decalaj)
{
if(s<=st&&dr<=f)
{
ma=max(ma,r[nod+decalaj]);
return;
}
int mij=(st+dr)/2;
if(s<=mij)
query(2*nod,st,mij,decalaj);
if(f>=mij+1)
query(2*nod+1,mij+1,dr,decalaj);
}
int main()
{
fin>>n>>m;
for(int i=1;i<=n;i++)
fin>>a[i];
for(int i=1;i<n;i++)
{
fin>>p>>q;
v[p].pb(q);
v[q].pb(p);
}
niv[1]=c[1]=1;
dfs(1);
for(int i=1;i<=nr;i++)
reverse(k[i].begin(),k[i].end());
for(int i=1;i<=nr;i++)
d[i]=d[i-1]+4*dim[i];
for(int i=1;i<=nr;i++)
for(auto j:k[i])
{
poz=niv[j]-niv[pr[i]];
val=a[j];
update(1,1,dim[i],d[i]);
}
for(int i=1;i<=m;i++)
{
fin>>type>>p>>q;
if(type==0)
{
val=q;
poz=niv[p]-niv[pr[l[p]]];
update(1,1,dim[l[p]],d[l[p]]);
continue;
}
ma=-1;
while(1)
{
if(l[p]==l[q])
{
if(niv[p]>niv[q])
swap(p,q);
s=niv[p]-niv[pr[l[p]]];
f=niv[q]-niv[pr[l[p]]];
query(1,1,dim[l[p]],d[l[p]]);
break;
}
if(niv[pr[l[p]]]<niv[pr[l[q]]])
swap(p,q);
s=1;
f=niv[p]-niv[pr[l[p]]];
query(1,1,dim[l[p]],d[l[p]]);
p=pr[l[p]];
}
fout<<ma<<'\n';
}
}