#include <bits/stdc++.h>
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
int n,m,ai[500005],poz[100005],l[100005],w[100005],d[100005],c[100005],lvl[100005],v[100005];
int cnt=0;
int path=1;
vector<int> G[100005];
void findw(int x, int dad)
{
w[x]=1;
for(auto it : G[x])
{
if(it!=dad)
{
findw(it,x);
w[x]+=w[it];
}
}
}
void HeavyPath(int x, int dad, int label, int level)
{
int son = 0;
l[x]=label;
poz[x]=(++cnt);
for(auto it : G[x])
{
if(it!=dad && w[it]>w[son])
{
son=it;
}
}
for(auto it : G[x])
{
if(it==dad)
{
continue;
}
if(it==son)
{
HeavyPath(it,x,label,level+1);
}
else
{
++path;
d[path]=x;
c[path]=it;
lvl[path]=level+1;
HeavyPath(it,x,path,level+1);
}
}
}
void update(int poz, int val, int nod, int a, int b)
{
if(a==b)
{
ai[nod]=val;
return;
}
int mij = (a+b)/2;
if(poz<=mij)
{
update(poz,val,nod*2,a,mij);
}
else
{
update(poz,val,nod*2+1,mij+1,b);
}
ai[nod]=max(ai[nod*2],ai[nod*2+1]);
}
int query(int qa, int qb, int nod, int a, int b)
{
if(qa<=a && qb>=b)
{
return ai[nod];
}
int mij = (a+b)/2;
int rez1=0,rez2=0;
if(qa<=mij)
{
rez1=query(qa,qb,nod*2,a,mij);
}
if(qb>mij)
{
rez2=query(qa,qb,nod*2+1,mij+1,b);
}
return max(rez1,rez2);
}
int query_arb(int x, int y)
{
int rez = 0;
while(l[x]!=l[y])
{
if(lvl[l[y]]<lvl[l[x]])
{
swap(x,y);
}
rez=max(rez,query(poz[c[l[y]]],poz[y],1,1,n));
y=d[l[y]];
}
if(poz[x]>poz[y])
{
swap(x,y);
}
rez=max(rez,query(poz[x],poz[y],1,1,n));
return rez;
}
int main()
{
f>>n>>m;
for(int i=1; i<=n; i++)
{
f>>v[i];
}
for(int i=1; i<n; i++)
{
int x,y;
f>>x>>y;
G[x].push_back(y);
G[y].push_back(x);
}
lvl[1]=1;
findw(1,0);
HeavyPath(1,0,1,1);
for(int i=1; i<=n; i++)
{
update(poz[i],v[i],1,1,n);
}
for(int i=1; i<=m; i++)
{
int t,x,y;
f>>t>>x>>y;
if(t==0)
{
update(poz[x],y,1,1,n);
}
else if(t==1)
{
g<<query_arb(x,y)<<'\n';
}
}
return 0;
}