#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>
#define DIMN 100001
using namespace std;
int lnt,nrc;
int d[DIMN],l[DIMN],poz[DIMN],up[DIMN],f[DIMN],val[DIMN],lvl[DIMN];
vector <int> v[DIMN],w[DIMN],aint[DIMN];
void precalc (int nod){
int i,vecin;
d[nod]=1;
f[nod]=1;
for (i=0;i<v[nod].size();i++){
vecin=v[nod][i];
if (!f[vecin]){
precalc (vecin);
d[nod]+=d[vecin];
lvl[vecin]=1+lvl[nod];
}
}
}
void dfs_lant(int nod,int tata){
int i,vecin,ok=0,maxi,fiu;
maxi=0;
fiu=0;
for (i=0;i<v[nod].size();i++){
vecin=v[nod][i];
if (vecin!=tata){
ok=1;
dfs_lant(vecin,nod);
if (d[vecin]>maxi){
maxi=d[vecin];
fiu=vecin;
}
}
}
if (!ok){ /// frunza
lnt++;
l[nod]=lnt; /// lantul din care apartine
w[lnt].push_back(nod);
}else { /// unim cu poz
w[l[fiu]].push_back(nod);
l[nod]=l[fiu];
for (i=0;i<v[nod].size();i++){
vecin=v[nod][i];
if (vecin!=tata && vecin!=fiu)
up[l[vecin]]=nod; /// din lantul vecinului trecem in lantul nodului
}
}
}
void build_aint (int lant,int p,int st,int dr){
int mid;
if (st==dr){
aint[lant][p]=val[w[lant][nrc]];
nrc++;
return;
}
mid=(st+dr)/2;
build_aint(lant,2*p,st,mid);
build_aint(lant,2*p+1,mid+1,dr);
aint[lant][p]=max(aint[lant][2*p],aint[lant][2*p+1]);
}
void update (int lant,int p,int st,int dr,int pf){
int mid;
if (st==dr){
aint[lant][p]=val[w[lant][pf]];
return;
}
mid=(st+dr)/2;
if (pf<=mid)
update(lant,2*p,st,mid,pf);
else update(lant,2*p+1,mid+1,dr,pf);
aint[lant][p]=max(aint[lant][2*p],aint[lant][2*p+1]);
}
int query_aint (int lant,int p,int st,int dr,int px,int py){
int sol=0,mid;
//if (lant==1 && px==1 && py==2)
// printf ("a");
if (px<=st && dr<=py)
return aint[lant][p];
mid=(st+dr)/2;
if (px<=mid)
sol=max(sol,query_aint(lant,2*p,st,mid,px,py));
if (mid+1<=py)
sol=max(sol,query_aint(lant,2*p+1,mid+1,dr,px,py));
return sol;
}
int query (int x,int y){
if (l[x]!=l[y]){ /// avansam
if (lvl[up[l[x]]]>lvl[up[l[y]]])
return max(query(up[l[x]],y) , query_aint(l[x],1,0,w[l[x]].size()-1,0,poz[x]));
else
return max(query(x,up[l[y]]) , query_aint(l[y],1,0,w[l[y]].size()-1,0,poz[y]));
}
else return query_aint(l[x],1,0,w[l[x]].size()-1,min(poz[x],poz[y]),max(poz[x],poz[y]));
}
int main()
{
FILE *fin=fopen ("heavypath.in","r");
FILE *fout=fopen ("heavypath.out","w");
int n,m,i,x,y,p,t,vecin;
fscanf (fin,"%d%d",&n,&m);
for (i=1;i<=n;i++){
fscanf (fin,"%d",&val[i]);
}
for (i=1;i<n;i++){
fscanf (fin,"%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
precalc(1);
/// imparte in lanturi
dfs_lant (1,0);
/// fiecare nod al catelea e
for (i=1;i<=lnt;i++){
reverse(w[i].begin(),w[i].end());
p=0;
for (vector <int> :: iterator j=w[i].begin();j!=w[i].end();j++){
/// pozitia lui din lantul curent
vecin=*j;
//printf ("%d ",vecin);
poz[vecin]=p;
p++;
}
//printf ("\n");
}
for (i=1;i<=lnt;i++){
aint[i].resize(w[i].size()*4);
nrc=0;
build_aint(i,1,0,w[i].size()-1);
}
for (;m;m--){
fscanf (fin,"%d%d%d",&t,&x,&y);
if (t==0){
val[x]=y;
update (l[x],1,0,w[l[x]].size()-1,poz[x]);
}
else
fprintf (fout,"%d\n",query (x,y));
}
return 0;
}