#include <bits/stdc++.h>
using namespace std;
ifstream in("heavypath.in");
ofstream out("heavypath.out");
int n,q,x,y,t,temp;
const int lim=1e5+3;
vector<int> vec[lim];
int papa[lim];
int val[lim];
int urm[lim];
int dp[lim];
int ad[lim];
bool ok[lim];
void df(int nod,int add)
{
ad[nod]=add;
ok[nod]=true;
int maxim=-1;
for(int x:vec[nod])
if(!ok[x])
{
df(x,add+1);
papa[x]=nod;
dp[nod]+=dp[x];
if(dp[x]>maxim)
maxim=dp[x],
urm[nod]=x;
}
}
int unde[lim];
struct path
{
int tata;
vector<int> tree;
vector<int> nodes;
path(int nod)
{
tata=nod;
nodes.clear();
nodes.push_back(0);
}
void init()
{
tree.clear();
tree.resize(4*nodes.size());
}
void build(int nod,int l,int r)
{
if(l==r)
{
tree[nod]=nodes[l];
return ;
}
int med=(l+r)>>1;
build(2*nod,l,med);
build(2*nod+1,med+1,r);
tree[nod]=max(tree[2*nod],tree[2*nod+1]);
}
void update(int nod,int l,int r,int poz,int vxl)
{
if(l==r)
{
tree[nod]=vxl;
return ;
}
int med=(l+r)>>1;
if(poz<=med) update(2*nod,l,med,poz,vxl);
else update(2*nod+1,med+1,r,poz,vxl);
tree[nod]=max(tree[2*nod],tree[2*nod+1]);
}
int query(int nod,int l,int r,int a,int b)
{
if(a<=l and r<=b)
return tree[nod];
int med=(l+r)>>1;
int ans1=0,ans2=0;
if(a<=med) ans1=query(2*nod,l,med,a,b);
if(b>med) ans2=query(2*nod+1,med+1,r,a,b);
return max(ans1,ans2);
}
};
path* buc[lim];
int nr[lim],cnt;
void make(int nod,int nrp)
{
nr[nod]=nrp;
path* p=buc[nrp];
unde[nod]=p->nodes.size();
p->nodes.push_back(val[nod]);
if(urm[nod]==0)
{
p->init();
p->build(1,1,p->nodes.size()-1);
return ;
}
make(urm[nod],nrp);
for(int x:vec[nod])
if(x!=papa[nod] and x!=urm[nod])
{
++cnt;
buc[cnt]=new path(x);
make(x,cnt);
}
}
int dmax(int x,int y)
{
int ans=0;
while(nr[x]!=nr[y])
{
if(ad[buc[nr[x]]->tata]<ad[buc[nr[y]]->tata]) swap(x,y);
ans=max(ans,buc[nr[x]]->query(1,1,buc[nr[x]]->nodes.size()-1,1,unde[x]));
x=papa[buc[nr[x]]->tata];
}
int jos=max(unde[x],unde[y]);
int sus=min(unde[x],unde[y]);
ans=max(ans,buc[nr[x]]->query(1,1,buc[nr[x]]->nodes.size()-1,sus,jos));
return ans;
}
int main()
{
in>>n>>q;
for(int i=1;i<=n;++i)
in>>val[i];
for(int i=1;i<n;++i)
{
in>>x>>y;
vec[x].push_back(y);
vec[y].push_back(x);
}
df(1,1);
cnt=1;
buc[1]=new path(1);
make(1,1);
for(int i=1;i<=q;++i)
{
in>>t>>x>>y;
if(t==0)
buc[nr[x]]->update(1,1,buc[nr[x]]->nodes.size()-1,unde[x],y);
else out<<dmax(x,y)<<'\n';
}
return 0;
}