#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
int m,n,vValNod[100001],vTati[100001],indiceLant;
int vGreutate[100001],vNiv[100001],lantCorespunzator[100001],pozInLant[100001];
vector <int> lanturi[100001];
vector <int> AI[100001];
vector <int> G[100001];
void citire()
{
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
scanf("%d",&vValNod[i]);
int aux1,aux2;
for(int i=1; i<n; i++)
{
scanf("%d%d",&aux1,&aux2);
vTati[aux2]=aux1;
G[aux1].push_back(aux2);
}
for(int i=1; i<=n; i++)
vGreutate[i]=1;
}
void dfs(int nod)
{
int maxx=0,nodmax=0;
vector <int> ::iterator IT;
if(G[nod].size()==0)
{
indiceLant++;
lantCorespunzator[nod]=indiceLant;
lanturi[indiceLant].push_back(nod);
pozInLant[nod]=1;
}
else
{
for(IT=G[nod].begin(); IT!=G[nod].end(); IT++)
{
vNiv[*IT]=vNiv[nod]+1;
dfs(*IT);
vGreutate[nod]+=vGreutate[*IT];
if(maxx<vGreutate[*IT])
{
maxx=vGreutate[*IT];
nodmax=*IT;
}
}
lanturi[lantCorespunzator[nodmax]].push_back(nod);
lantCorespunzator[nod]=lantCorespunzator[nodmax];
pozInLant[nod]=pozInLant[nodmax]+1;
}
}
void buildArb(int nrLant,int pai,int st,int dr)
{
if(st==dr)
{
AI[nrLant][pai]=vValNod[lanturi[nrLant][st]];
return;
}
int mij=(st+dr)/2;
buildArb(nrLant,2*pai,st,mij);
buildArb(nrLant,2*pai+1,mij+1,dr);
AI[nrLant][pai]=max(AI[nrLant][2*pai],AI[nrLant][2*pai+1]);
}
void updateArbore(int nrLant,int pai,int st,int dr,int cetrebuieSchimbat,int cuCeTrebuieSchimbat)
{
if(st==dr)
{
AI[nrLant][pai]=cuCeTrebuieSchimbat;
return;
}
int mij=(st+dr)/2;
if(mij>=cetrebuieSchimbat)
updateArbore(nrLant,2*pai,st,mij,cetrebuieSchimbat,cuCeTrebuieSchimbat);
else
updateArbore(nrLant,2*pai+1,mij+1,dr,cetrebuieSchimbat,cuCeTrebuieSchimbat);
AI[nrLant][pai]=max(AI[nrLant][2*pai],AI[nrLant][2*pai+1]);
}
int maxInterval;
void aflareMaxim(int nrLant,int pai,int st,int dr,int intervalS,int intervalD)
{
if(st>=intervalS&&dr<=intervalD)
{
maxInterval=max(maxInterval,AI[nrLant][pai]);
return;
}
int mij=(st+dr)/2;
if(mij>=intervalS)
aflareMaxim(nrLant,pai*2,st,mij,intervalS,intervalD);
if(mij<intervalD)
aflareMaxim(nrLant,pai*2+1,mij+1,dr,intervalS,intervalD);
}
int main()
{
freopen("heavypath.in","r",stdin);
freopen("heavypath.out","w",stdout);
citire();
dfs(1);
for(int i=1; i<=indiceLant; i++)
{
for(int j=0; j<lanturi[i].size(); j++)
printf("%d ",lanturi[i][j]);
printf("\n");
}
for(int i=1; i<=indiceLant; i++)
{
AI[i].resize(4*lanturi[i].size());
buildArb(i,1,0,lanturi[i].size()-1);
}
int t,aux1,aux2;
for(int i=1; i<=m; i++)
{
scanf("%d%d%d",&t,&aux1,&aux2);
if(t==0)
{
updateArbore(lantCorespunzator[aux1],1,0,lanturi[lantCorespunzator[aux1]].size(),aux1,aux2);
}
else
{
maxInterval=0;
while(lantCorespunzator[aux1]!=lantCorespunzator[aux2])
{
if(vNiv[*(lanturi[lantCorespunzator[aux1]].end()-1)]<vNiv[*(lanturi[lantCorespunzator[aux2]].end()-1)])
{
aflareMaxim(lantCorespunzator[aux1],1,0,lanturi[lantCorespunzator[aux1]].size()-1,pozInLant[aux1],lanturi[lantCorespunzator[aux1]].size());
aux1=vTati[*(lanturi[lantCorespunzator[aux1]].end()-1)];
}
else
{
aflareMaxim(lantCorespunzator[aux2],1,0,lanturi[lantCorespunzator[aux2]].size()-1,pozInLant[aux2],lanturi[lantCorespunzator[aux2]].size());
aux2=vTati[*(lanturi[lantCorespunzator[aux2]].end()-1)];
}
}
aflareMaxim(lantCorespunzator[aux1],1,1,lanturi[lantCorespunzator[aux1]].size(),min(pozInLant[aux1],pozInLant[aux2]),max(pozInLant[aux1],pozInLant[aux2]));
printf("%d\n",maxInterval);
}
}
return 0;
}