#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],dp[18][100005],niv[100005];
int pathpar[100005],poz[100005],lg[100005];
int in[100005],out[100005],timp;
vector<vector<int>> arb;
vector<int> muchii[1005];
vector<int> path[1005];
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;
dp[0][nod]=par[nod];
for(int i=1;i<=17;i++)
dp[i][nod]=dp[i-1][dp[i-1][nod]];
for(auto i:muchii[nod])
if(i!=par[nod])
{
niv[i]=niv[nod]+1;
par[i]=nod;
dfs(i);
nr[nod]+=nr[i];
}
for(auto i:muchii[nod])
if(i!=par[nod])
if(nr[i]>=nr[nod]/2+nr[nod]%2)
isheavy[i]=1;
timp++;
out[nod]=timp;
}
bool isancestor(int x,int y)
{
return niv[x]<=niv[y]&&in[x]<=in[y]&&out[x]>=out[y];
}
int lca(int x,int y)
{
if(niv[x]>niv[y])
swap(x,y);
if(isancestor(x,y))
return x;
for(int i=17;i>=0;i--)
if(dp[i][x]!=0&&!isancestor(dp[i][x],y))
x=dp[i][x];
return par[x];
}
int getmax(int y,int x)
{
int rez=0;
while(true)
{
if(what[y]==what[x])
{
rez=max(rez,query(what[y],1,1,lg[what[y]],poz[y],poz[x]));
y=x;
break;
}
else
{
rez=max(rez,query(what[y],1,1,lg[what[y]],poz[y],lg[what[y]]));
y=pathpar[what[y]];
}
}
return rez;
}
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];
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[nrpath].push_back(nod);
what[nod]=nrpath;
while(isheavy[nod])
{
nod=par[nod];
what[nod]=nrpath;
path[nrpath].push_back(nod);
}
}
}
vector<int> a;
arb.push_back(a);
for(int i=1;i<=nrpath;i++)
{
a.clear();
//reverse(path[i].begin(),path[i].end());
lg[i]=path[i].size();
for(int j=0;j<=5*path[i].size();j++)
a.push_back(0);
arb.push_back(a);
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--)
{
bool ok=0;
int tip,x,y;
fin>>tip>>x>>y;
if(m==9)
ok=1;
if(tip==0)
update(what[x],1,1,lg[what[x]],poz[x],y);
else
{
int LCA=lca(x,y);
int rez=max(getmax(x,LCA),getmax(y,LCA));
if(rez==0)
ok=1;
fout<<rez<<'\n';
}
}
return 0;
}