#include <fstream>
#include <vector>
#define MAXN 100005
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
int t,n,m,v[MAXN],tata[MAXN],tatal[MAXN],x,y,xx,lant[MAXN],pozlant[MAXN],poz,nrl,lvl[MAXN],mxq,ls,ld,mxai,aux2;
vector<int> G[MAXN],lanturi[MAXN],vlanturi[MAXN];
vector<int> ai[MAXN];
int MAX(int a,int b);
void DFS(int p);
void build_ai(int nod,int st,int dr);
void update_ai(int nod,int st,int dr);
void query(int a,int b);
void query_ai(int nod,int st,int dr);
int main()
{
int i,j,k;
f>>n>>m;
for(i=1;i<=n;i++)
f>>v[i];
for(i=1;i<n;i++){
f>>x>>y;
G[x].push_back(y);
G[y].push_back(x);}
tata[1]=-1;
lvl[1]=1;
DFS(1);
for(i=1;i<=nrl;i++){
for(j=lanturi[i].size()-1;j>=0;j--){
x=lanturi[i][j];
for(k=1;k<=4;k++)
ai[i].push_back(0);
vlanturi[i].push_back(v[x]);
pozlant[x]=vlanturi[i].size()-1;}
x=i;
build_ai(1,0,lanturi[i].size()-1);}
for(i=1;i<=m;i++){
f>>t>>x>>y;
if(t){
mxq=0;
query(x,y);
g<<mxq<<'\n';}
else{
xx=lant[x];
poz=pozlant[x];
update_ai(1,0,lanturi[xx].size()-1);}}
f.close();
g.close();
return 0;
}
int MAX(int a,int b){
return (a>b)?a:b;}
void DFS(int p){
int i,mx=0,mxi;
if(G[p].size()==1&&tata[p]!=-1){
lanturi[++nrl].push_back(p);
lant[p]=nrl;
return;}
for(i=0;i<G[p].size();i++){
x=G[p][i];
if(!tata[x]){
lvl[x]=lvl[p]+1;
tata[x]=p;
DFS(x);
x=G[p][i];
if(lanturi[lant[x]].size()>mx){
mx=lanturi[lant[x]].size();
mxi=i;}}}
for(i=0;i<G[p].size();i++){
if(i==mxi||tata[p]==G[p][i])
continue;
tatal[lant[G[p][i]]]=p;}
lanturi[lant[G[p][mxi]]].push_back(p);
lant[p]=lant[G[p][mxi]];}
void build_ai(int nod,int st,int dr){
int mij;
if(st==dr){
ai[x][nod]=vlanturi[x][st];
return;}
mij=(st+dr)/2;
build_ai(2*nod,st,mij);
build_ai(2*nod+1,mij+1,dr);
ai[x][nod]=MAX(ai[x][2*nod],ai[x][2*nod+1]);}
void update_ai(int nod,int st,int dr){
int mij;
if(st==dr){
ai[xx][nod]=y;
return;}
mij=(st+dr)/2;
if(poz<=mij)
update_ai(2*nod,st,mij);
else
update_ai(2*nod+1,mij+1,dr);
ai[xx][nod]=MAX(ai[xx][2*nod],ai[xx][2*nod+1]);}
void query_ai(int nod,int st,int dr){
int mij;
if(st>=ls&&dr<=ld){
if(ai[x][nod]>mxai)
mxai=ai[x][nod];
return;}
mij=(st+dr)/2;
if(ls<=mij)
query_ai(2*nod,st,mij);
if(ld>mij)
query_ai(2*nod+1,mij+1,dr);}
void query(int a,int b){
if(lant[a]==lant[b]){
x=lant[a];
if(pozlant[a]>pozlant[b]){
ls=pozlant[b];
ld=pozlant[a];}
else{
ls=pozlant[a];
ld=pozlant[b];}
mxai=0;
query_ai(1,0,lanturi[x].size()-1);
if(mxai>mxq)
mxq=mxai;
return;}
if(lvl[tatal[lant[a]]]<lvl[tatal[lant[b]]]){
aux2=a;
a=b;
b=aux2;}
x=lant[a];
mxai=0;
ls=0;
ld=pozlant[a];
query_ai(1,0,lanturi[x].size()-1);
if(mxai>mxq)
mxq=mxai;
query(tatal[x],b);}