#include <bits/stdc++.h>
#define Nmax 100005
#define ls (((nod+1)<<1)-1)
#define rs (ls+1)
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
list <int> arb[Nmax];
int t[Nmax],lvl[Nmax],nr_chain[Nmax],weight[Nmax],poz[Nmax],v[Nmax];
vector <int> chain[Nmax],Aint[Nmax];
int n,Q,N;
void DFS(int x)
{
weight[x]=1;
list <int> :: iterator it;
int nod=0;
bool is_leaf=true;
for(it=arb[x].begin();it!=arb[x].end();++it)
if(!lvl[*it])
{
is_leaf=false;
lvl[*it]=lvl[x]+1;
t[*it]=x;
DFS(*it);
if(weight[*it]>weight[nod]) nod=*it;
weight[x]+=weight[*it];
}
if(is_leaf)
{
chain[++N].push_back(x);
nr_chain[x]=N;
}
else
{
chain[nr_chain[nod]].push_back(x);
nr_chain[x]=nr_chain[nod];
}
}
int nr_arb,lsh,rsh,look_for,ans,val;
void build(int p, int q, int nod)
{
if(p==q) Aint[nr_arb][nod]=v[chain[nr_arb][p]];
else
{
int m=(p+q)>>1;
build(p,m,ls);
build(m+1,q,rs);
Aint[nr_arb][nod]=max(Aint[nr_arb][ls],Aint[nr_arb][rs]);
}
}
void update(int p, int q, int nod)
{
if(p==q) Aint[nr_arb][nod]=val;
else
{
int m=(p+q)>>1;
if(look_for<=m) update(p,m,ls);
else update(m+1,q,rs);
Aint[nr_arb][nod]=max(Aint[nr_arb][ls],Aint[nr_arb][rs]);
}
}
int query(int p, int q, int nod)
{
if(lsh<=p and q<=rsh) return Aint[nr_arb][nod];
else
{
int m=(p+q)>>1,max1=-INT_MAX,max2=-INT_MAX;
if(lsh<=m) max1=query(p,m,ls);
if(m<rsh) max2=query(m+1,q,rs);
return max(max1,max2);
}
}
void heavy_path(int x, int y)
{
ans=-INT_MAX;
while(nr_chain[x]!=nr_chain[y])
{
if(lvl[chain[nr_chain[x]][0]]<lvl[chain[nr_chain[y]][0]])
swap(x,y);
nr_arb=nr_chain[x];
lsh=0;
rsh=poz[x];
val=query(0,chain[nr_arb].size()-1,0);
if(val>ans) ans=val;
x=t[chain[nr_chain[x]][0]];
}
nr_arb=nr_chain[x];
lsh=min(poz[x],poz[y]);
rsh=poz[x]+poz[y]-lsh;
val=query(0,chain[nr_arb].size()-1,0);
if(val>ans) ans=val;
g<<ans<<'\n';
}
int main()
{
f>>n>>Q;
int i,j,k;
for(i=1;i<=n;i++)
f>>v[i];
for(k=1;k<n;k++)
{
f>>i>>j;
arb[i].push_back(j);
arb[j].push_back(i);
}
lvl[1]=1;
DFS(1);
for(k=1;k<=N;k++)
{
reverse(chain[k].begin(),chain[k].end());
for(i=0;i<chain[k].size();i++)
poz[chain[k][i]]=i;
Aint[k].resize(4*chain[k].size());
nr_arb=k;
build(0,chain[k].size()-1,0);
}
bool op;
int x,y;
while(Q--)
{
f>>op>>x>>y;
if(op)
{
heavy_path(x,y);
}
else
{
val=y;
v[x]=y;
nr_arb=nr_chain[x];
look_for=poz[x];
update(0,chain[nr_arb].size()-1,0);
}
}
return 0;
}