#include<iostream>
#include<fstream>
#include<vector>
#include<algorithm>
using namespace std;
#define NMAX 100001
vector <int> v[NMAX],p[NMAX],a[NMAX];
int whatpath[NMAX],whatpoz[NMAX],weight[NMAX],niv[NMAX],parent[NMAX],viz[NMAX],tata[NMAX],val[NMAX],nrp,rez;
void dfs(int nod)
{
int frunza,fiu;
viz[nod]=1;
frunza=1;
fiu=0;
weight[nod]=1;
for(vector <int> :: iterator it=v[nod].begin();it!=v[nod].end();it++)
if(viz[*it]==0) {
frunza=0;
niv[*it]=niv[nod]+1;
dfs(*it);
tata[*it]=nod;
weight[nod]=weight[nod]+weight[*it];
if(fiu==0)
fiu=*it;
else if(weight[*it]>weight[fiu])
fiu=*it;
}
if(frunza) {
nrp++;
whatpath[nod]=nrp;
p[nrp].push_back(nod);
}
else {
p[whatpath[fiu]].push_back(nod);
whatpath[nod]=whatpath[fiu];
}
}
void built(int nod, int st, int dr, int path)
{
int mij;
if(st==dr) {
a[path][nod]=val[p[path][st]];
return ;
}
mij=(st+dr)/2;
built(nod*2,st,mij,path);
built(nod*2+1,mij+1,dr,path);
a[path][nod]=max(a[path][nod*2],a[path][nod*2+1]);
}
void makepaths()
{
int i;
dfs(1);
for(i=1;i<=nrp;i++) {
reverse(p[i].begin(),p[i].end());
for(vector <int> :: iterator it=p[i].begin();it!=p[i].end();it++)
whatpoz[*it]=it-p[i].begin();
a[i].resize(4*p[i].size());
built(1,0,p[i].size()-1,i);
parent[i]=tata[*p[i].begin()];
}
}
void update(int nod, int st, int dr, int poz, int val, int path)
{
int mij;
if(st==dr) {
a[path][nod]=val;
return ;
}
mij=(st+dr)/2;
if(poz<=mij)
update(nod*2,st,mij,poz,val,path);
else update(nod*2+1,mij+1,dr,poz,val,path);
a[path][nod]=max(a[path][nod*2],a[path][nod*2+1]);
}
void query(int nod, int st, int dr, int first, int second, int path)
{
int mij;
if(first<=st && dr<=second) {
rez=max(rez,a[path][nod]);
return ;
}
mij=(st+dr)/2;
if(first<=mij)
query(nod*2,st,mij,first,second,path);
if(mij<second)
query(nod*2+1,mij+1,dr,first,second,path);
}
int which(int x, int y)
{
if(whatpath[x]==whatpath[y]) {
rez=-1;
query(1,0,p[whatpath[x]].size()-1,min(whatpoz[x],whatpoz[y]),max(whatpoz[x],whatpoz[y]),whatpath[x]);
return rez;
}
int p1,p2,val;
p1=whatpath[x];
p2=whatpath[y];
if(niv[parent[p1]]>niv[parent[p2]] || (parent[p2]==0)) {
swap(x,y);
swap(p1,p2);
}
rez=-1;
query(1,0,p[whatpath[y]].size()-1,0,whatpoz[y],whatpath[y]);
val=rez;
return max(val,which(x,parent[p2]));
}
int main ()
{
int n,m,i,x,y,opt;
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].push_back(y);
v[y].push_back(x);
}
makepaths();
for(i=1;i<=m;i++) {
f>>opt>>x>>y;
if(opt==0)
update(1,0,p[whatpath[x]].size()-1,whatpoz[x],y,whatpath[x]);
else g<<which(x,y)<<'\n';
}
f.close();
g.close();
return 0;
}