#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
const int MAXN=100010;
ifstream f("heavypath.in");
ofstream o("heavypath.out");
vector <int> G[MAXN],P[MAXN];
int rez,aux,sol,fol[MAXN],w[MAXN],nl,aint[4*MAXN];
int x,y,n,m,v[MAXN],i,niv[MAXN],lant[MAXN],parent[MAXN],poz[MAXN],dim[MAXN],lNiv[MAXN];
struct operatie{int t; int x; int y;};
operatie op[MAXN];
int df(int nod)
{
w[nod]=1;
fol[nod]=1;
int frunza=1,he=-1;
for (vector<int>::iterator it=G[nod].begin();it!=G[nod].end();++it)
{
if (fol[*it]) continue;
frunza=0;
niv[*it]=niv[nod]+1;
df(*it);
w[nod]+=w[*it];
if (he==-1)
he=*it;
else if (w[he]<w[*it]) he=*it;
}
if (frunza)
{
lant[nod]=++nl;
++dim[nl];
P[nl].push_back(nod);
return 0;
}
lant[nod]=lant[he];
++dim[lant[he]];
P[lant[he]].push_back(nod);
for (vector<int>::iterator it=G[nod].begin();it!=G[nod].end();++it)
{
if (*it==he || niv[*it]<niv[nod])
continue;
parent[lant[*it]]=nod;
lNiv[lant[*it]]=nod;
}
return 0;
}
int build(int nod,int st,int dr,int decalaj,int lan)
{
if (st==dr)
{
aint[nod+decalaj]=v[P[lan][st-1]];
return 0;
}
int med=(st+dr)/2;
build(nod*2,st,med,decalaj,lan);
build(nod*2+1,med+1,dr,decalaj,lan);
aint[nod+decalaj]=aint[nod*2+decalaj];
if (aint[nod+decalaj]<aint[nod*2+1+decalaj]) aint[nod+decalaj]=aint[nod*2+1+decalaj];
return 0;
}
int update(int nod,int st,int dr,int poz,int val,int decalaj)
{
if (st==dr)
{
aint[nod+decalaj]=val;
return 0;
}
int med=(st+dr)/2;
if (poz<=med)
update(nod*2,st,med,poz,val,decalaj);
else update(nod*2+1,med+1,dr,poz,val,decalaj);
aint[nod+decalaj]=aint[nod*2+decalaj];
if (aint[nod+decalaj]<aint[nod*2+1+decalaj])
aint[nod+decalaj]=aint[nod*2+1+decalaj];
return 0;
}
int query(int nod,int st,int dr,int qst,int qdr,int decalaj)
{
if (qst<=st && qdr>=dr)
return aint[nod+decalaj];
int med=(st+dr)/2;
if (qst<=med)
{
aux=query(nod*2,st,med,qst,qdr,decalaj);
if (rez<aux) rez=aux;
}
if (qdr>med)
{
aux=query(nod*2+1,med+1,dr,qst,qdr,decalaj);
if (rez<aux) rez=aux;
}
return rez;
}
int main(void)
{
f>>n>>m;
for (i=1;i<=n;i++) f>>v[i];
for (i=1;i<n;i++)
{
f>>x>>y;
G[x].push_back(y);
G[y].push_back(x);
}
for (i=1;i<=m;i++)
f>>op[i].t>>op[i].x>>op[i].y;
niv[1]=1;
df(1);
for (i=1;i<=nl;i++)
{
reverse(P[i].begin(),P[i].end());
if (i>1)
poz[i]=poz[i-1]+4*dim[i-1];
build(1,1,dim[i],poz[i],i);
}
for (i=1;i<=m;i++)
{
x=op[i].x;
y=op[i].y;
if (op[i].t==0)
update(1,1,dim[lant[x]],niv[x]-lNiv[lant[x]],y,poz[lant[x]]);
else
{
sol=0;
while (1)
{
if (lant[x]==lant[y])
{
if (niv[x]>niv[y])
{
aux=y;
y=x;
x=aux;
}
rez=0;
aux=query(1,1,dim[lant[x]],niv[x]-lNiv[lant[x]],niv[y]-lNiv[lant[x]],poz[lant[x]]);
if (sol<aux) sol=aux;
break;
}
if (lNiv[lant[x]]<lNiv[lant[y]])
{
aux=y;
y=x;
x=aux;
}
rez=0;
aux=query(1,1,dim[lant[x]],1,niv[x]-lNiv[lant[x]],poz[lant[x]]);
if (sol<aux) sol=aux;
x=parent[lant[x]];
}
o<<sol<<"\n";
}
}
return 0;
}