#include <cstdio>
#include <vector>
#define pb push_back
#define DIM 10000
using namespace std;
char buff[DIM];
int poz=0;
void citeste(int &numar)
{
numar = 0;
while (buff[poz] < '0' || buff[poz] > '9')
if (++poz == DIM)
fread(buff,1,DIM,stdin),poz=0;
while ('0'<=buff[poz] && buff[poz]<='9')
{
numar = numar*10 + buff[poz] - '0';
if (++poz == DIM)
fread(buff,1,DIM,stdin),poz=0;
}
}
const int nmax=100023;
int n,m;
vector<int>adj[nmax],arb[nmax];
int val[nmax],fre;
int weight[nmax],sze[nmax],chain[nmax],tata[nmax],root[nmax],niv[nmax],place_in_chain[nmax];
bool vis[nmax];
void dfs(const int &nod,const int &nivel)
{
niv[nod]=nivel;
weight[nod]=1;
vis[nod]=1;
vector<int>::iterator it;
int maxim=0,which=0;
for(it=adj[nod].begin();it!=adj[nod].end();++it)
{
if(vis[*it]) continue;
tata[*it]=nod;
dfs(*it,nivel+1);
weight[nod]+=weight[*it];
if(maxim<weight[*it])
{
maxim=weight[*it];
which=*it;
}
}
if(maxim==0)
{
chain[nod]=++fre;
sze[chain[nod]]=1;
place_in_chain[nod]=1;
root[chain[nod]]=nod;
return;
}
chain[nod]=chain[which];
sze[chain[nod]]++;
place_in_chain[nod]=place_in_chain[which]+1;
root[chain[nod]]=nod;
}
void update(const int &pre,const int &st,const int &dr,const int &nod,const int &pos)
{
if(st==dr) arb[pre][nod]=val[pos];
else
{
int mij=(st+dr)/2;
if(place_in_chain[pos]<=mij) update(pre,st,mij,2*nod,pos);
else update(pre,mij+1,dr,2*nod+1,pos);
arb[pre][nod]=max(arb[pre][2*nod],arb[pre][2*nod+1]);
}
}
int query(const int &pre,const int st,int &dr,const int &p1,const int &p2,const int &nod)
{
if(st==p1&&p2==dr) return arb[pre][nod];
else
{
int mij=(st+dr)/2;
if(p2<=mij) return query(pre,st,mij,p1,p2,2*nod);
else if(p1>mij) return query(pre,mij+1,dr,p1,p2,2*nod+1);
return max(query(pre,st,mij,p1,mij,2*nod),query(pre,mij+1,dr,mij+1,p2,2*nod+1));
}
}
int main()
{
freopen ("heavypath.in","r",stdin);
freopen ("heavypath.out","w",stdout);
citeste(n),citeste(m);
for(int i=1;i<=n;i++) citeste(val[i]);
for(int i=1;i<n;i++)
{
int a,b;
citeste(a),citeste(b);
adj[a].pb(b);
adj[b].pb(a);
}
dfs(1,1);
for(int i=1;i<=fre;i++) arb[i].resize(sze[i]*4);
for(int i=1;i<=n;i++)
{
update(chain[i],1,sze[chain[i]],1,i);
}
for(int i=1;i<=m;i++)
{
int a,b,c;
citeste(a),citeste(b),citeste(c);
if(a==0)
{
val[b]=c;
update(chain[b],1,sze[chain[b]],1,b);
}
else
{
int rasp=0;
while(1)
{
// printf("%d %d\n",b,c);
if(chain[b]==chain[c])
{
int p1=place_in_chain[b],p2=place_in_chain[c];
rasp=max(query(chain[b],1,sze[chain[b]],min(p1,p2),max(p1,p2),1),rasp);
break;
}
else
{
if(niv[root[chain[b]]]<niv[root[chain[c]]]) swap(b,c);
rasp=max(query(chain[b],1,sze[chain[b]],place_in_chain[b],place_in_chain[root[chain[b]]],1),rasp);
b=tata[root[chain[b]]];
}
}
printf("%d\n",rasp);
}
}
}