#include <bits/stdc++.h>
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
int n,m,val[100005],niv[100005],in[100005],out[100005];
vector<int> muchii[100005];
int where[100005],poz[100005];
int par[100005];
bool isheavy[100005];
int timp,nr[100005];
vector<vector<int>> arb;
vector<int> emp;
vector<vector<int>> path;
int lg[100005];
void dfs(int nod)
{
timp++;
in[nod]=timp;
nr[nod]=1;
for(int i:muchii[nod])
if(i!=par[nod])
{
par[i]=nod;
niv[i]=niv[nod]+1;
dfs(i);
nr[nod]+=nr[i];
}
out[nod]=timp;
int who=0,maxim=0;
for(int i:muchii[nod])
if(i!=par[nod])
if(nr[i]>maxim)
{
maxim=nr[i];
who=i;
}
if(maxim>0)
isheavy[who]=1;
}
void arbupdate(int ind,int nod,int st,int dr,int p,int x)
{
if(st==dr)
{
arb[ind][nod]=x;
return;
}
int mij=(st+dr)/2;
if(p<=mij)
arbupdate(ind,nod*2,st,mij,p,x);
else
arbupdate(ind,nod*2+1,mij+1,dr,p,x);
arb[ind][nod]=max(arb[ind][nod*2],arb[ind][nod*2+1]);
}
int arbquery(int ind,int nod,int st,int dr,int a,int b)
{
if(st>=a&&dr<=b)
return arb[ind][nod];
int mij=(st+dr)/2;
int rez=0;
if(a<=mij)
rez=max(rez,arbquery(ind,nod*2,st,mij,a,b));
if(b>mij)
rez=max(rez,arbquery(ind,nod*2+1,mij+1,dr,a,b));
return rez;
}
bool isancestor(int a,int b)
{
return in[a]<=in[b]&&out[a]>=out[b];
}
void build()
{
path.push_back(emp);
arb.push_back(emp);
int cnt=0;
for(int start=1;start<=n;start++)
{
bool good=1;
for(int i:muchii[start])
if(i!=par[start])
if(isheavy[i])
good=0;
if(good)
{
vector<int> pp;
cnt++;
arb.push_back(emp);
int nod=start;
while(true)
{
pp.push_back(nod);
if(isheavy[nod])
nod=par[nod];
else
break;
}
for(int i=0;i<pp.size();i++)
{
where[pp[i]]=cnt;
poz[pp[i]]=i+1;
}
int lg=pp.size();
path.push_back(pp);
arb[cnt].resize(4*lg+5);
}
}
}
void update(int nod,int val)
{
int ind=where[nod];
int p=poz[nod];
arbupdate(ind,1,1,path[ind].size(),p,val);
}
int query(int a,int b)
{
int rez=0;
while(true)
{
int ind=where[a];
int p=poz[a];
if(!isancestor(path[ind].back(),b))
{
rez=max(rez,arbquery(ind,1,1,path[ind].size(),p,path[ind].size()));
a=par[path[ind].back()];
continue;
}
else
{
int st=p;
int dr=path[ind].size();
int last=1e9;
while(st<=dr)
{
int mij=(st+dr)/2;
if(isancestor(path[ind][mij-1],b))
{
last=mij;
dr=mij-1;
}
else
st=mij+1;
}
rez=max(rez,arbquery(ind,1,1,path[ind].size(),p,last));
break;
}
}
return rez;
}
int main()
{
ios_base::sync_with_stdio(false);
fin.tie(0);
fin>>n>>m;
for(int i=1;i<=n;i++)
fin>>val[i];
for(int i=1;i<n;i++)
{
int a,b;
fin>>a>>b;
muchii[a].push_back(b);
muchii[b].push_back(a);
}
niv[1]=1;
dfs(1);
build();
for(int i=1;i<=n;i++)
update(i,val[i]);
while(m--)
{
int tip;
fin>>tip;
if(tip==0)
{
int nod,x;
fin>>nod>>x;
val[nod]=x;
update(nod,x);
}
else
{
int a,b;
fin>>a>>b;
fout<<max(query(a,b),query(b,a))<<'\n';
}
}
return 0;
}