#include <bits/stdc++.h>
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
int n,m,val[100005],par[100005],nr[100005],isheavy[100005],nrpath,what[100005],niv[100005];
int pathpar[100005],poz[100005],lg[100005];
int in[100005],out[100005],timp;
int **arb;
vector<vector<int>> muchii;
vector<vector<int>> path;
void update(int index,int nod,int st,int dr,int poz,int val)
{
if(st==dr)
{
arb[index][nod]=val;
return;
}
int mij=(st+dr)/2;
if(poz<=mij)
update(index,nod*2,st,mij,poz,val);
else
update(index,nod*2+1,mij+1,dr,poz,val);
arb[index][nod]=max(arb[index][nod*2],arb[index][nod*2+1]);
}
int query(int index,int nod,int st,int dr,int a,int b)
{
if(st>=a&&dr<=b)
return arb[index][nod];
int mij=(st+dr)/2;
int rez=0;
if(a<=mij)
rez=max(rez,query(index,nod*2,st,mij,a,b));
if(b>mij)
rez=max(rez,query(index,nod*2+1,mij+1,dr,a,b));
return rez;
}
void dfs(int nod)
{
timp++;
in[nod]=timp;
nr[nod]=1;
if(niv[nod]==0)
niv[nod]=1;
int best=0;
int maxim=0;
for(auto i:muchii[nod])
if(i!=par[nod])
{
niv[i]=niv[nod]+1;
par[i]=nod;
dfs(i);
nr[nod]+=nr[i];
if(maxim<nr[i])
{
maxim=nr[i];
best=i;
}
}
if(best!=0)
isheavy[best]=1;
timp++;
out[nod]=timp;
}
int getmax(int x,int y)
{
if(what[x]==what[y])
return query(what[y],1,1,lg[what[y]],min(poz[x],poz[y]),max(poz[x],poz[y]));
if(niv[path[what[x]][lg[what[x]]-1]]>=niv[path[what[y]][lg[what[y]]-1]])
return max(getmax(x,path[what[x]][lg[what[x]]-1]),getmax(pathpar[what[x]],y));
else
{
swap(x,y);
return max(getmax(x,path[what[x]][lg[what[x]]-1]),getmax(pathpar[what[x]],y));
}
}
int main()
{
ios_base::sync_with_stdio(false);
fin.tie(0);
fout.tie(0);
fin>>n>>m;
for(int i=1;i<=n;i++)
fin>>val[i];
muchii.resize(n+1);
for(int i=1;i<n;i++)
{
int a,b;
fin>>a>>b;
muchii[a].push_back(b);
muchii[b].push_back(a);
}
dfs(1);
for(int i=1;i<=n;i++)
{
bool found=0;
int nod=i;
for(auto j:muchii[nod])
if(j!=par[nod])
if(isheavy[j]==1)
found=1;
if(found==0)
{
nrpath++;
path.resize(nrpath+1);
path[nrpath].push_back(nod);
what[nod]=nrpath;
while(isheavy[nod])
{
nod=par[nod];
what[nod]=nrpath;
path[nrpath].push_back(nod);
}
}
}
arb=new int *[nrpath+1];
//assert(nrpath<=30);
for(int i=1;i<=nrpath;i++)
{
//reverse(path[i].begin(),path[i].end());
lg[i]=path[i].size();
arb[i]=new int [4*lg[i]+1];
for(int j=0;j<path[i].size();j++)
{
poz[path[i][j]]=j+1;
pathpar[i]=par[path[i][j]];
}
}
for(int i=1;i<=n;i++)
update(what[i],1,1,lg[what[i]],poz[i],val[i]);
while(m--)
{
int tip,x,y;
fin>>tip>>x>>y;
if(tip==0)
update(what[x],1,1,lg[what[x]],poz[x],y);
else
{
int rez=getmax(x,y);
fout<<rez<<'\n';
}
}
return 0;
}