#include <fstream>
#include <vector>
using namespace std;
ifstream in("heavypath.in");
ofstream out("heavypath.out");
const int NMAX=1e5+5, LMAX=17;
int n, m, val[NMAX], p[NMAX], d[NMAX], hc[NMAX];
int dtlca, dthv, clc=1, pozlca[NMAX], pozhv[NMAX], lc[NMAX];
vector<int> adj[NMAX];
struct RMQ
{
int rmq[LMAX+1][2*NMAX];
void build()
{
for(int b=1;b<=LMAX;b++)
for(int i=1;i+(1<<b)-1<=dtlca;i++)
if(d[rmq[b-1][i]]<d[rmq[b-1][i+(1<<(b-1))]])
rmq[b][i]=rmq[b-1][i];
else
rmq[b][i]=rmq[b-1][i+(1<<(b-1))];
}
int query(int l, int r)
{
if(l>r)
swap(l, r);
int lg=31-__builtin_clz(r-l+1);
if(rmq[lg][l]<rmq[lg][r-(1<<lg)+1])
return rmq[lg][l];
return rmq[lg][r-(1<<lg)+1];
}
}dslca;
struct AINT
{
int aint[4*NMAX];
void update(int nod, int l, int r, int poz, int val)
{
if(poz<l || r<poz)
return;
if(l==r)
{
aint[nod]=val;
return;
}
int mid=(l+r)/2;
update(2*nod, l, mid, poz, val);
update(2*nod+1, mid+1, r, poz, val);
aint[nod]=max(aint[2*nod], aint[2*nod+1]);
}
int query(int nod, int l, int r, int ql, int qr)
{
if(qr<l || r<ql)
return 0;
if(ql<=l && r<=qr)
return aint[nod];
int mid=(l+r)/2;
return max(query(2*nod, l, mid, ql, qr),
query(2*nod+1, mid+1, r, ql, qr));
}
}dshv;
int DFS(int u, int pu)
{
int maxsz=0, szu=1;
for(auto v:adj[u])
if(v!=pu)
{
d[v]=d[u]+1; p[v]=u;
int szv=DFS(v, u);
szu+=szv;
if(szv>maxsz)
{
maxsz=szv;
hc[u]=v;
}
}
return szu;
}
void DFSord(int u, int pu)
{
dslca.rmq[0][++dtlca]=u;
pozlca[u]=dtlca;
dthv++; pozhv[u]=dthv; lc[u]=clc;
dshv.update(1, 1, n, dthv, val[u]);
if(hc[u]>0)
{
DFSord(hc[u], u);
dslca.rmq[0][++dtlca]=u;
}
for(auto v:adj[u])
if(v!=pu && v!=hc[u])
{
clc=v;
DFSord(v, u);
dslca.rmq[0][++dtlca]=u;
}
}
int hvquery(int u, int su)
{
int ans=0;
while(d[su]<d[lc[u]])
{
ans=max(ans, dshv.query(1, 1, n, pozhv[lc[u]], pozhv[u]));
u=p[lc[u]];
}
ans=max(ans, dshv.query(1, 1, n, pozhv[su], pozhv[u]));
return ans;
}
int main()
{
in>>n>>m;
for(int i=1;i<=n;i++)
in>>val[i];
for(int i=1;i<n;i++)
{
int a, b; in>>a>>b;
adj[a].push_back(b);
adj[b].push_back(a);
}
DFS(1, 0);
DFSord(1, 0);
dslca.build();
while(m--)
{
int t, x, y;
in>>t>>x>>y;
if(t==0)
dshv.update(1, 1, n, pozhv[x], y);
else
{
int lca=dslca.query(pozlca[x], pozlca[y]);
out<<max(hvquery(x, lca), hvquery(y, lca))<<'\n';
}
}
return 0;
}