#include <bits/stdc++.h>
#define Nmax 100001
#define ls (((nod+1)<<1)-1)
#define rs ((nod+1)<<1)
#define DIM 700000
using namespace std;
char buffer[DIM];
int cursor=DIM-1;
void read(int &x)
{
x=0;
while(!isdigit(buffer[cursor]))
if(++cursor==DIM)
{
cursor=0;
fread(buffer,1,DIM,stdin);
}
while(isdigit(buffer[cursor]))
{
x=x*10+buffer[cursor]-'0';
if(++cursor==DIM)
{
cursor=0;
fread(buffer,1,DIM,stdin);
}
}
}
int v[Nmax],nr_chain[Nmax],poz[Nmax],lvl[Nmax],weight[Nmax],t[Nmax];
list <int> arb[Nmax];
vector <int> chain[Nmax];
vector <int> Aint[Nmax];
int N,changed,nr_arb,lsh,rsh;
void DFS(int x)
{
int nr=0,nod=0;
for(list <int> :: iterator it=arb[x].begin();it!=arb[x].end();++it)
if(!lvl[*it])
{
nr++;
t[*it]=x;
lvl[*it]=lvl[x]+1;
DFS(*it);
if(weight[*it]>weight[nod])
nod=*it;
}
weight[x]=nr+1;
if(nr)
{
nr_chain[x]=nr_chain[nod];
chain[nr_chain[x]].push_back(x);
}
else
{
nr_chain[x]=++N;
chain[N].push_back(x);
}
}
inline bool cmp(const int &x, const int &y)
{
return lvl[x]<lvl[y];
}
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]=v[chain[nr_arb][p]];
else
{
int m=(p+q)>>1;
if(changed<=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);
}
}
int heavy_path_query(int x, int y)
{
int maxx=-1;
while(nr_chain[x]!=nr_chain[y])
{
if(lvl[chain[nr_chain[x]][0]]<lvl[chain[nr_chain[y]][0]]) swap(x,y);
lsh=0;
rsh=poz[x];
nr_arb=nr_chain[x];
maxx=max(maxx,query(0,chain[nr_arb].size()-1,0));
x=t[chain[nr_chain[x]][0]];
}
nr_arb=nr_chain[x];
lsh=poz[x];
rsh=poz[y];
if(lsh>rsh) swap(lsh,rsh);
return max(maxx,query(0,chain[nr_arb].size()-1,0));
}
int main()
{
freopen("heavypath.in","r",stdin);
freopen("heavypath.out","w",stdout);
int n,Q,i,j,x,y,op;
read(n);
read(Q);
for(i=1;i<=n;i++)
read(v[i]);
for(i=1;i<n;i++)
{
read(x);
read(y);
arb[x].push_back(y);
arb[y].push_back(x);
}
lvl[1]=1;
DFS(1);
for(i=1;i<=N;i++)
{
sort(chain[i].begin(),chain[i].end(),cmp);
for(j=0;j<(int)chain[i].size();j++)
poz[chain[i][j]]=j;
Aint[i].resize(4*chain[i].size());
nr_arb=i;
build(0,chain[i].size()-1,0);
}
while(Q--)
{
read(op);
read(x);
read(y);
if(!op)
{
v[x]=y;
nr_arb=nr_chain[x];
changed=poz[x];
update(0,chain[nr_arb].size()-1,0);
}
else
printf("%d\n",heavy_path_query(x,y));
}
return 0;
}