#include<iostream>
#include<fstream>
#include<vector>
#include<algorithm>
using namespace std;
#define pb push_back
const int NMAX = 100001;
const int MMAX = 100001;
vector <int> v[NMAX],path[NMAX],arb[NMAX];
int subarb[NMAX],lant[NMAX],poz[NMAX],up[NMAX],val[NMAX],niv[NMAX],paths,valmax;
void dfs(int nod, int parinte, int lev)
{
int smax;
subarb[nod]=1;
niv[nod]=lev;
for(vector <int> :: iterator it=v[nod].begin();it!=v[nod].end();it++)
if(*it!=parinte) {
up[*it]=nod;
dfs(*it,nod,lev+1);
subarb[nod]=subarb[nod]+subarb[*it];
}
if(v[nod].size()==1 && nod!=1) {
path[++paths].pb(0);
path[paths].pb(nod);
lant[nod]=paths;
poz[nod]=1;
return ;
}
smax=0;
for(vector <int> :: iterator it=v[nod].begin();it!=v[nod].end();it++)
if(*it!=parinte && subarb[*it]>subarb[smax])
smax=*it;
lant[nod]=lant[smax];
path[lant[smax]].pb(nod);
poz[nod]=path[lant[smax]].size()-1;
}
void init(int nod, int st, int dr, int paths)
{
int mij;
if(st==dr) {
arb[paths][nod]=val[path[paths][st]];
return ;
}
mij=(st+dr)/2;
init(nod*2,st,mij,paths);
init(nod*2+1,mij+1,dr,paths);
arb[paths][nod]=max(arb[paths][nod*2],arb[paths][nod*2+1]);
}
void update(int nod, int st, int dr, int paths, int qpoz, int y)
{
int mij;
if(st==dr) {
arb[paths][nod]=y;
return ;
}
mij=(st+dr)/2;
if(qpoz<=mij)
update(nod*2,st,mij,paths,qpoz,y);
else update(nod*2+1,mij+1,dr,paths,qpoz,y);
arb[paths][nod]=max(arb[paths][nod*2],arb[paths][nod*2+1]);
}
void query(int nod, int st, int dr, int paths, int a, int b)
{
int mij;
if((a<=st)&&(dr<=b)) {
if(arb[paths][nod]>valmax)
valmax=arb[paths][nod];
return ;
}
mij=(st+dr)/2;
if(a<=mij)
query(nod*2,st,mij,paths,a,b);
if(mij<b)
query(nod*2+1,mij+1,dr,paths,a,b);
}
int maxim(int x, int y)
{
int ret;
ret=val[x];
while(x!=y) {
if(niv[x]>niv[y])
swap(x,y);
if(lant[x]==lant[y]) {
valmax=-1;
query(1,1,path[lant[y]].size()-1,lant[y],poz[x],poz[y]);
ret=max(ret,valmax);
y=x;
}
else {
valmax=-1;
query(1,1,path[lant[y]].size()-1,lant[y],1,poz[y]);
ret=max(ret,valmax);
y=up[path[lant[y]][1]];
}
}
return ret;
}
int main ()
{
int n,m,i,x,y,tip;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
f>>n>>m;
for(i=1;i<=n;i++)
f>>val[i];
for(i=1;i<=n-1;i++) {
f>>x>>y;
v[x].pb(y);
v[y].pb(x);
}
dfs(1,0,1);
for(i=1;i<=paths;i++) {
reverse(path[i].begin()+1,path[i].end());
for(vector <int> :: iterator it=path[i].begin()+1;it!=path[i].end();it++)
poz[*it]=path[i].size()-poz[*it];
arb[i].resize(4*(path[i].size()+1));
init(1,1,path[i].size()-1,i);
}
for(i=1;i<=m;i++) {
f>>tip>>x>>y;
if(tip==0) {
val[x]=y;
update(1,1,path[lant[x]].size()-1,lant[x],x,y);
}
else
g<<maxim(x,y)<<'\n';
}
f.close();
g.close();
return 0;
}