#include <fstream>
#include <vector>
#include <algorithm>
#define INF 100001
using namespace std;
ifstream fi ("heavypath.in");
ofstream fo ("heavypath.out");
vector<int> v[200005],vaux;
vector<vector<int>> lant,aib;
int nivel[200005],eul[400005],val[100005],reprez[200005],tata[200005],pozinlant[200005];
int nrnod,nrq,lgeul,nrlant;
bool comp(int a,int b)
{
return nivel[a]<nivel[b];
}
int dfslant(int nod,int lvl,int prev)
{
nivel[nod]=lvl;
if (v[nod].size()==1 and prev!=0)
{
nrlant++;
reprez[nod]=nrlant-1;
lant.push_back(vaux);
lant[nrlant-1].push_back(nod);
return 1;
}
int stot=0,smax=0;
for (int i=0;i<v[nod].size();i++)
{
int nextnod=v[nod][i];
if (nextnod==prev) continue;
int sum=dfslant(nextnod,lvl+1,nod);
stot+=sum;
if (sum>smax)
{
smax=sum;
reprez[nod]=reprez[nextnod];
}
}
lant[reprez[nod]].push_back(nod);
for (int i=0;i<v[nod].size();i++)
{
int nextnod=v[nod][i];
if (nextnod==prev) continue;
if (reprez[nod]!=reprez[nextnod]) tata[reprez[nextnod]]=nod;
}
return stot+1;
}
int genaib(int idx,int nod,int st,int dr)
{
if (st==dr) return aib[idx][nod]=lant[idx][st];
int mij=(st+dr)/2;
int nod1=genaib(idx,nod*2,st,mij);
int nod2=genaib(idx,nod*2+1,mij+1,dr);
if (val[nod1]>val[nod2]) return aib[idx][nod]=nod1;
else return aib[idx][nod]=nod2;
}
int update(int idx,int nod,int st,int dr,int nr,int valoare)
{
int poz=pozinlant[nr];
if (st==dr)
{
val[nr]=valoare;
return nr;
}
int nod1=0,nod2=0;
int mij=(st+dr)/2;
if (poz<=mij)
{
nod1=update(idx,nod*2,st,mij,nr,valoare);
nod2=aib[idx][nod*2+1];
}
else
{
nod1=aib[idx][nod*2];
nod2=update(idx,nod*2+1,mij+1,dr,nr,valoare);
}
if (val[nod1]>=val[nod2]) return aib[idx][nod]=nod1;
else aib[idx][nod]=nod2;
}
int qaib(int idx,int nod,int st,int dr,int start,int stop)
{
if (start>stop) swap(start,stop);
if (dr<start or st>stop) return 0;
if (st>=start and dr<=stop) return aib[idx][nod];
int mij=(st+dr)/2;
int nod1=qaib(idx,nod*2,st,mij,start,stop);
int nod2=qaib(idx,nod*2+1,mij+1,dr,start,stop);
if (val[nod1]>val[nod2]) return nod1;
else return nod2;
}
int querry(int nod1,int nod2)
{
int idx1=reprez[nod1];
int idx2=reprez[nod2];
int nodcur=0;
int nodaux=0;
while (idx1!=idx2)
{
int tata1=tata[idx1];
int tata2=tata[idx2];
if (nivel[tata1]<nivel[tata2])
{
swap (tata1,tata2);
swap(idx1,idx2);
swap(nod1,nod2);
}
nodaux=qaib(idx1,1,0,lant[idx1].size()-1,0,pozinlant[nod1]);
if (val[nodaux]>val[nodcur]) nodcur=nodaux;
nod1=tata[idx1];
idx1=reprez[nod1];
idx2=reprez[nod2];
}
nodaux=qaib(idx1,1,0,lant[idx1].size()-1,pozinlant[nod1],pozinlant[nod2]);
if (nodcur==0) return val[nodaux];
if (val[nodcur]>val[nodaux]) return val[nodcur];
return val[nodaux];
}
int main()
{
fi>>nrnod>>nrq;
for (int i=1;i<=nrnod;i++) fi>>val[i];
for (int i=1;i<nrnod;i++)
{
int x,y;
fi>>x>>y;
v[x].push_back(y);
v[y].push_back(x);
}
nivel[INF]=INF;nivel[0]=-1;
int aux=dfslant(1,0,0);
for (int i=0;i<nrlant;i++) sort(lant[i].begin(),lant[i].end(),comp);
for (int i=0;i<nrlant;i++)
for (int j=0;j<lant[i].size();j++)
pozinlant[lant[i][j]]=j;
for (int i=0;i<nrlant;i++)
{
aib.push_back(vaux);
for (int j=0;j<=lant[i].size()*4;j++) aib[i].push_back(-1);
aux=genaib(i,1,0,lant[i].size()-1);
}
// for (int i=0;i<nrlant;i++)
// {
// fo<<i<<':';
// for (int j=0;j<lant[i].size();j++) fo<<lant[i][j]<<' ';
// fo<<"tata: "<<tata[i];
// fo<<'\n';
// }
for (int i=1;i<=nrq;i++)
{
int p,x,y;
fi>>p>>x>>y;
if (p==0) aux=update(reprez[x],1,0,lant[reprez[x]].size()-1,x,y);
if (p==1) fo<<querry(x,y)<<'\n';
}
// for (int i=1;i<aib[0].size();i++) fo<<aib[0][i]<<' ';
return 0;
}