#include <bits/stdc++.h>
#define nmx 100005
using namespace std;
int n,val[nmx],m,a,b,rsp,ord[nmx],ct,sef[nmx],jos[nmx],nr[nmx],arb[4*nmx],where[nmx],up[20][nmx],par[nmx],st[nmx],dr[nmx],ctl;
int niv[nmx];
vector <int> v[nmx];
void dfs(int source,int father)
{
par[source]=father;
niv[source]=niv[father]+1;
up[0][source]=father;
///ord[++ct]=source;
///where[source]=ct;
int ok=0,mx=0,ctm=0,which;
for (auto it : v[source])
if (it!=father)
{
dfs(it,source);
ok=1;
if (nr[it]>mx)
{
mx=nr[it];
ctm++;
which=it;
}
else if (nr[it]==mx)
ctm++;
}
if (!ok)
{
sef[source]=source;
jos[source]=source;
nr[source]=1;
return;
///frunza
}
if (ctm>=2)
mx++;
sef[jos[which]]=source;
jos[source]=jos[which];
nr[source]=mx;
}
void build (int st,int dr,int index)
{
if (st==dr)
{
arb[index]=val[ord[st]];
//cout<<st<<' '<<dr<<' '<<arb[index]<<'\n';
return;
}
int mid=(st+dr)/2;
build(st,mid,index*2);
build(mid+1,dr,index*2+1);
arb[index]=max(arb[index*2],arb[index*2+1]);
//cout<<st<<' '<<dr<<' '<<arb[index]<<'\n';
}
void update(int st,int dr,int poz,int val,int index)
{
if (st==dr)
{
arb[index]=val;
return;
}
int mid=(st+dr)/2;
if (poz<=mid)
update(st,mid,poz,val,index*2);
else update(mid+1,dr,poz,val,index*2+1);
arb[index]=max(arb[index*2],arb[index*2+1]);
}
int query(int st,int dr,int a,int b,int index)
{
if (b<st || dr<a)
return 0;
if (a<=st && dr<=b)
return arb[index];
int mid=(st+dr)/2;
return max(query(st,mid,a,b,index*2),query(mid+1,dr,a,b,index*2+1));
}
void doit(int x,int boss)
{
while (sef[jos[x]]!=sef[jos[boss]])
{
//cout<<x<<' ';
int r=query(1,n,where[x],where[sef[jos[x]]],1);
rsp=max(rsp,r);
x=par[sef[jos[x]]];
}
//cout<<x<<' '<<"poz"<<' '<<where[x]<<' '<<where[boss]<<'\n';
int r=query(1,n,where[x],where[boss],1);
rsp=max(rsp,r);
}
int main()
{
ifstream f ("heavypath.in");
ofstream g ("heavypath.out");
f>>n>>m;
for (int i=1; i<=n; i++)
f>>val[i];
for (int i=1; i<n; i++)
{
f>>a>>b;
v[a].push_back(b);
v[b].push_back(a);
}
dfs(1,0);
for (int i=1; i<=n; i++)
{
if (jos[i]==i)
{
int j=i;
///ctl nr de lanturi
///ct pe ce pozitie sunt
///st cea mai din stanga poz a unui lant
///dr cea mai din dreapta
///ord e vectoru
///where e a cata pozitie din lant e
st[++ctl]=++ct;
ord[ct]=j;
where[j]=ct;
while (par[j]!=par[sef[i]])
{
j=par[j];
ord[++ct]=j;
where[j]=ct;
}
dr[ctl]=ct;
}
v[i].clear();
}
build(1,n,1);
int p2=0,p=1;
while (p*2<=n)
p*=2,p2++;
for (int j=1; j<=p2; j++)
for (int i=1; i<=n; i++)
up[j][i]=up[j-1][up[j-1][i]];
//for (int i=1; i<=n; i++)
// cout<<ord[i]<<' ';
//cout<<'\n';
//for (int i=1;i<=n;i++)
//cout<<i<<' '<<"sef "<<sef[jos[i]]<<' '<<"baza"<<' '<<jos[i]<<'\n';
int c;
while (m--)
{
f>>c>>a>>b;
if (c==0)
{
update(1,n,where[a],b,1);
val[a]=b;
}
else
{
if (niv[a]>niv[b])
swap(a,b);
int b2=b,a2=a,lca=0;
int dif=niv[b]-niv[a];
///b mai jos
for (int i=p2; i>=0; i--)
{
if ((1<<i)<=dif)
{
dif-=(1<<i);
b2=up[i][b2];
}
}
//cout<<b2<<' ';
if (a2!=b2)
for (int i=p2; i>=0; i--)
{
if (up[i][a2]!=up[i][b2])
{
a2=up[i][a2];
b2=up[i][b2];
}
else lca=up[i][a2];
}
else lca=a2;
if (!lca) lca=a2;
rsp=0;
if (lca!=a) doit(a,lca);
else rsp=val[a];
if (lca!=b) doit(b,lca);
else rsp=max(rsp,val[b]);
g<<rsp<<'\n';
}
}
}