#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream fin ("heavypath.in");
ofstream fout ("heavypath.out");
vector <int> v[100001],noduri_lant[100001],aint[100001];
int n,q,i,j,x,y,ch,sol,nr,st,dr,nod,val,valnr[100001];
int nivinit[100001],t[100001],lant[100001],lg_lant[100001],dp[100001],nivel[100001];
void build (int nod,int st,int dr,int poz)
{
if (st==dr)
aint[poz][nod]=valnr[noduri_lant[i][st-1]];
else
{
int mij=(st+dr)/2;
build (2*nod,st,mij,poz);
build (2*nod+1,mij+1,dr,poz);
aint[poz][nod]=max (aint[poz][2*nod],aint[poz][2*nod+1]);
}
}
void update (int nod,int st,int dr,int pozi,int val,int poz)
{
if (st==dr)
aint[poz][nod]=val;
else
{
int mij=(st+dr)/2;
if (pozi<=mij)
update (2*nod,st,mij,poz,val,poz);
else
update (2*nod+1,mij+1,dr,poz,val,poz);
aint[poz][nod]=max (aint[poz][2*nod],aint[poz][2*nod+1]);
}
}
void query (int nod,int st,int dr,int a,int b,int &sol,int poz)
{
if (st>=a&&dr<=b)
sol=max (sol,aint[poz][nod]);
else
{
int mij=(st+dr)/2;
if (a<=mij)
query (2*nod,st,mij,a,b,sol,poz);
if (b>=mij+1)
query (2*nod+1,mij+1,dr,a,b,sol,poz);
}
}
void dfs (int nod,int tt,int niv)
{
int poz=0;
for (int i=0; i<v[nod].size (); i++)
{
int vecin=v[nod][i];
if (vecin!=tt)
{
dfs (vecin,nod,niv+1);
if (dp[vecin]>dp[nod])
{
dp[nod]=dp[vecin];
poz=vecin;
}
}
}
dp[nod]++;
nivinit[nod]=niv;
if (poz==0)
{
nr++;
lant[nod]=nr;
noduri_lant[lant[nod]].push_back (nod);
}
else
{
lant[nod]=lant[poz];
noduri_lant[lant[nod]].push_back (nod);
}
for (int i=0; i<v[nod].size (); i++)
{
int vecin=v[nod][i];
if (vecin!=tt&&vecin!=poz)
t[lant[vecin]]=nod;
}
}
int main ()
{
fin>>n>>q;
for (i=1; i<=n; i++)
fin>>valnr[i];
for (i=1; i<n; i++)
{
fin>>x>>y;
v[x].push_back (y);
v[y].push_back (x);
}
dfs (1,0,1);
for (i=1; i<=nr; i++)
{
lg_lant[i]=noduri_lant[i].size ();
aint[i].resize (4*lg_lant[i]+1,0);
reverse (noduri_lant[i].begin (),noduri_lant[i].end ());
build (1,1,lg_lant[i],i);
for (j=0; j<noduri_lant[i].size (); j++)
nivel[noduri_lant[i][j]]=j+1;
}
while (q--)
{
fin>>ch;
if (ch==0)
{
fin>>nod>>val;
update (1,1,lg_lant[lant[nod]],nivel[nod],val,lant[nod]);
}
else
{
fin>>x>>y;
sol=0;
while (lant[x]!=lant[y])
{
if (nivinit[t[lant[x]]]>=nivinit[t[lant[y]]])
{
query (1,1,lg_lant[lant[x]],1,nivel[x],sol,lant[x]);
x=t[lant[x]];
}
else
{
query (1,1,lg_lant[lant[y]],1,nivel[y],sol,lant[y]);
y=t[lant[y]];
}
}
st=min (nivel[x],nivel[y]);
dr=max (nivel[x],nivel[y]);
query (1,1,lg_lant[lant[x]],st,dr,sol,lant[x]);
fout<<sol<<"\n";
}
}
return 0;
}