#include <bits/stdc++.h>
using namespace std;
ifstream in("heavypath.in");
ofstream out("heavypath.out");
const int lim=1e5+4;
struct lant
{
vector<int> tree;
vector<int> v;
lant* tata;
int vf;
void build(int nod,int l,int r)
{
if(l==r)
{
tree[nod]=v[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)
{
if(l==r)
{
tree[nod]=v[l];
return ;
}
int med=(l+r)>>1;
if(poz<=med) update(2*nod,l,med,poz);
else update(2*nod+1,med+1,r,poz);
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);
}
};
vector<int> vec[lim];
lant* casa[lim];
bool viz[lim];
int papa[lim];
int ind[lim];
int add[lim];
int val[lim];
int dim[lim];
int n,q,t,x,y;
void df(int nod)
{
dim[nod]=1;
viz[nod]=true;
for(int x:vec[nod])
if(!viz[x])
{
add[x]=add[nod]+1;
df(x);
papa[x]=nod;
dim[nod]+=dim[x];
}
}
void df2(int nod)
{
int maxim=0,unde=0;
for(int x:vec[nod])
if(x!=papa[nod])
{
if(dim[x]>=maxim)
maxim=dim[x],
unde=x;
}
if(unde==0)
return ;
casa[unde]=casa[nod];
ind[unde]=casa[unde]->v.size();
casa[unde]->v.push_back(val[unde]);
df2(unde);
for(int x:vec[nod])
if(x!=papa[nod] and x!=unde)
{
casa[x]=new lant();
casa[x]->vf=x;
ind[x]=casa[x]->v.size();
casa[x]->tata=casa[nod];
casa[x]->v.push_back(val[x]);
df2(x);
casa[x]->tree.resize(4*casa[x]->v.size());
casa[x]->build(1,0,casa[x]->v.size()-1);
}
}
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);
casa[1]=new lant();
casa[1]->vf=1;
ind[1]=casa[1]->v.size();
casa[1]->v.push_back(val[1]);
df2(1);
casa[1]->tree.resize(4*casa[1]->v.size());
casa[1]->build(1,0,casa[1]->v.size()-1);
while(q--)
{
in>>t>>x>>y;
if(t==0)
{
casa[x]->v[ind[x]]=y;
casa[x]->update(1,0,casa[x]->v.size()-1,ind[x]);
continue;
}
int maxim=0;
while(casa[x]->vf!=casa[y]->vf)
{
if(add[casa[x]->vf]<add[casa[y]->vf])
swap(x,y);
maxim=max(maxim,casa[x]->query(1,0,casa[x]->v.size()-1,0,ind[x]));
x=papa[casa[x]->vf];
}
if(ind[x]>ind[y])
swap(x,y);
maxim=max(maxim,casa[x]->query(1,0,casa[x]->v.size()-1,ind[x],ind[y]));
out<<maxim<<'\n';
}
return 0;
}