#include<bits/stdc++.h>
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
int n,i,m;
vector<int>v[100001];
int nr[100001],t[100001],depth[100001],val[100001];
int lant[100001];
bool viz[100001];
int pozlant[100001];
vector<int>vallant[100001];
int nrv,poz[100001];
vector<int>arb[100001];
void dfst(int nod,int prt)
{
for(auto q:v[nod])
{
if(q!=prt)
{
t[q]=nod;
dfst(q,nod);
}
}
}
void dfs(int nod)
{
for(auto q:v[nod])
{
if(q!=t[nod])
{
depth[q]=depth[nod]+1;
dfs(q);
nr[nod]+=nr[q];
}
}
nr[nod]++;
}
void dfs2(int nod)
{
if(lant[nod])
return;
int pop=-1;
for(auto q:v[nod])
if(q!=t[nod])
{
dfs2(q);
if(pop<nr[q])
{
lant[nod]=lant[q];
pop=nr[q];
}
}
}
void update(int poz,int nr,int st,int dr,int p,int pl)
{
if(st==dr)
{
arb[pl][poz]=nr;
return;
}
int mid=(st+dr)/2;
if(p<=mid)
update(poz*2,nr,st,mid,p,pl);
else
update(poz*2+1,nr,mid+1,dr,p,pl);
arb[pl][poz]=max(arb[pl][poz*2],arb[pl][poz*2+1]);
}
int query(int qst,int qdr,int st,int dr,int poz,int pl)
{
if(st>=qst&&dr<=qdr)
return arb[pl][poz];
if(st>qdr)
return -1;
if(dr<qst)
return -1;
int mid=(st+dr)/2;
int a,b;
a=query(qst,qdr,st,mid,poz*2,pl);
b=query(qst,qdr,mid+1,dr,poz*2+1,pl);
return max(a,b);
}
int main()
{
fin>>n>>m;
for(i=1;i<=n;i++)
fin>>val[i];
for(i=1;i<n;i++)
{
int a,b;
fin>>a>>b;
v[a].push_back(b);
v[b].push_back(a);
}
dfst(1,0);
dfs(1);
for(int i=2;i<=n;i++)
if(v[i].size()==1)
lant[i]=i;
dfs2(1);
for(int i=2;i<=n;i++)
{
if(v[i].size()==1)
{
int nod=i;
while(lant[t[nod]]==lant[i])
nod=t[nod];
int nod2=i;
while(nod2!=t[nod])
{
viz[nod2]=true;
pozlant[nod2]=depth[nod2]-depth[nod]+1;
lant[nod2]=nod;
nod2=t[nod2];
}
}
}
fill(viz,viz+100001,0);
for(int i=2;i<=n;i++)
{
if(v[i].size()==1)
{
nrv++;
int nod=i;
while(lant[nod]==lant[i])
{
vallant[nrv].push_back(val[nod]);
viz[nod]=true;
poz[nod]=nrv;
nod=t[nod];
}
}
}
for(int i=1;i<=nrv;i++)
{
for(int j=0;j<(vallant[i].size()+1)/2;j++)
swap(vallant[i][j],vallant[i][vallant[i].size()-1-j]);
for(auto q:vallant[i])
{
for(int j=1;j<=5;j++)
{
arb[i].push_back(0);
}
}
}
for(int i=1;i<=nrv;i++)
{
for(int j=0;j<vallant[i].size();j++)
{
update(1,vallant[i][j],1,vallant[i].size(),j+1,i);
}
}
for(int i=1;i<=m;i++)
{
int op,a,b;
fin>>op>>a>>b;
if(op==0)
{
update(1,b,1,vallant[poz[a]].size(),pozlant[a],poz[a]);
}
else
{
int maxim=0;
while(lant[a]!=lant[b])
{
if(depth[lant[b]]>depth[lant[a]])
{
maxim=max(maxim,query(1,pozlant[b],1,vallant[poz[b]].size(),1,poz[b]));
int tt=lant[b];
b=t[lant[b]];
}
else
{
maxim=max(maxim,query(1,pozlant[a],1,vallant[poz[a]].size(),1,poz[a]));
a=t[lant[a]];
}
}
if(pozlant[a]>pozlant[b])
swap(a,b);
maxim=max(maxim,query(pozlant[a],pozlant[b],1,vallant[poz[a]].size(),1,poz[a]));
fout<<maxim<<"\n";
}
}
}