#include <bits/stdc++.h>
#define INF 1e8+1
#define VMAX 100005
//#define int long long int
using namespace std;
ifstream fin ("heavypath.in");
ofstream fout ("heavypath.out");
int n;
int top[VMAX];
int sz[VMAX];
int tin[VMAX];
int heavy[VMAX];
vector<int> graf[VMAX];
int timer=0;
int depth[VMAX];
int tata[VMAX];
void decomp(int nod, int crt_top)
{
tin[nod]=++timer;
top[nod]=crt_top;
if(heavy[nod])
{
decomp(heavy[nod],nod); // cobor in fiul heavy
}
for(auto it:graf[nod])
{
if(tin[it])
continue;
decomp(it,it); // it devine noul top
}
}
void dfs(int nod, int parinte)
{
tata[nod]=parinte;
sz[nod]=1;
int maxim=0;
for(auto it:graf[nod])
{
if(it==parinte)
continue;
depth[it]=depth[nod]+1;
dfs(it,nod);
if(sz[it]>sz[maxim])
maxim=it;
sz[nod]+=sz[it];
}
heavy[nod]=maxim;
}
int aint[4*VMAX];
int val_init[VMAX];
void update(int st, int dr, int poz, int nr, int val)
{
if(st==dr)
{
aint[nr]=val;
return;
}
int mij = (st+dr)/2;
if(poz<=mij)
update(st,mij,poz,2*nr,val);
else
update(mij+1,dr,poz,2*nr+1,val);
aint[nr]=max(aint[2*nr],aint[2*nr+1]);
}
int query(int st, int dr, int st_interv, int dr_interv, int nr)
{
if(st_interv<=st && dr<=dr_interv)
return aint[nr];
int mij = (st+dr)/2,maxim=-INF;
if(mij>=st_interv)
maxim = max(maxim,query(st,mij,st_interv,dr_interv,2*nr));
if(mij+1<=dr_interv)
maxim=max(maxim,query(mij+1,dr,st_interv,dr_interv,2*nr+1));
return maxim;
}
int get_lca(int u, int v) {
// Jump from chain to chain until both nodes are on the same heavy path
while (top[u] != top[v]) {
// Always move the node whose chain head is deeper in the tree
if (depth[top[u]] > depth[top[v]]) {
u = tata[top[u]];
} else {
v = tata[top[v]];
}
}
// Once they are on the same chain, the one with the smaller depth is the LCA
if (depth[u] < depth[v]) return u;
return v;
}
int get_max_hld(int inc, int fin)
{
int maxim=-INF;
while(depth[top[inc]]>=depth[fin])
{
// iau tot lantul heavy
maxim=max(maxim,query(1,n,tin[top[inc]],tin[inc],1));
inc = top[inc];
if(inc==fin)
break;
inc = tata[inc];
}
// de la inc la fin
maxim=max(maxim,query(1,n,tin[fin],tin[inc],1));
return maxim;
}
int main()
{
int m,i,j,k,t,q,nr,minim,maxim,suma, lca;
fin>>n>>m;
for(i=1;i<=n;i++)
{
fin>>val_init[i];
}
for(i=1;i<n;i++)
{
fin>>j>>k;
graf[j].push_back(k);
graf[k].push_back(j);
}
tin[0]=VMAX;
dfs(1,0);
decomp(1,1);
for(i=1;i<=n;i++)
{
update(1,n,tin[i],1,val_init[i]);
}
while(m--)
{
fin>>i>>j>>k;
if(i==0)
{
update(1,n,tin[j],1,k);
}
else
{
lca=get_lca(j,k);
maxim=get_max_hld(j,lca);
maxim=max(maxim,get_max_hld(k,lca));
fout<<maxim<<'\n';
}
}
return 0;
}