#include <stdio.h>
#include <vector>
#include <algorithm>
#define NMAX 100005
#define LMAX (1<<18)
#define pb push_back
using namespace std;
int n,m,r,val[NMAX],nr[NMAX],fii[NMAX],dad[NMAX],lvl[NMAX],L[NMAX],which[NMAX],best[NMAX],nl,poz[NMAX],C[NMAX],D[NMAX],arb[LMAX],rez;
vector <int> A[NMAX],B[NMAX];
char viz[NMAX];
void read()
{
scanf("%d%d",&n,&m);
int i,a,b;
for (i=1; i<=n; i++)
scanf("%d",&val[i]);
for (i=1; i<n; i++)
{
scanf("%d%d",&a,&b);
A[a].pb(b);
A[b].pb(a);
}
}
void dfs(int nod)
{
viz[nod]=1;
nr[nod]=1;
int i,vec;
for (i=0; i<A[nod].size(); i++)
{
vec=A[nod][i];
if (!viz[vec])
{
lvl[vec]=lvl[nod]+1;
fii[nod]++;
dfs(vec);
nr[nod]+=nr[vec];
if (nr[vec]>nr[best[nod]])
best[nod]=vec;
}
}
if (!fii[nod])
{
nl++;
L[nl]=1; which[nod]=nl;
B[nl].pb(nod);
return ;
}
L[which[best[nod]]]++;
B[which[best[nod]]].pb(nod);
which[nod]=which[best[nod]];
for (i=0; i<A[nod].size(); i++)
{
vec=A[nod][i];
if (vec!=best[nod] && lvl[vec]>lvl[nod])
dad[which[vec]]=nod;
}
}
void chains()
{
dfs(1);
int i,j,nod;
for (i=1; i<=nl; i++)
reverse(B[i].begin(),B[i].end());
for (i=1; i<=nl; i++)
{
if (i>1)
D[i]=D[i-1]+B[i-1].size();
else
D[i]=1;
for (j=0; j<B[i].size(); j++)
{
nod=B[i][j];
C[++r]=nod;
poz[nod]=r;
}
}
}
inline int max(int x,int y)
{
return x>y ? x : y;
}
void update(int st,int dr,int nod,int position,int value)
{
if (st==dr)
{
arb[nod]=value;
return ;
}
int mij=(st+dr)/2;
if (position<=mij)
update(st,mij,nod*2,position,value);
else
update(mij+1,dr,nod*2+1,position,value);
arb[nod]=max(arb[nod*2],arb[nod*2+1]);
}
int query(int st,int dr,int nod,int a,int b)
{
if (b<st || a>dr)
return 0;
if (a<=st && dr<=b)
return arb[nod];
int mij=(st+dr)/2;
return max(query(st,mij,nod*2,a,b),query(mij+1,dr,nod*2+1,a,b));
}
void solve()
{
int i,tip,x,y;
lvl[0]=-1;
for (i=1; i<=n; i++)
update(1,n,1,poz[i],val[i]);
for (i=1; i<=m; i++)
{
scanf("%d%d%d",&tip,&x,&y);
if (tip==0)
update(1,n,1,poz[x],y);
else
{
rez=0;
while (which[x]!=which[y])
{
if (lvl[dad[which[x]]]<lvl[dad[which[y]]])
swap(x,y);
rez=max(rez,query(1,n,1,D[which[x]],poz[x]));
x=dad[which[x]];
}
if (poz[x]>poz[y])
swap(x,y);
rez=max(rez,query(1,n,1,poz[x],poz[y]));
printf("%d\n",rez);
}
}
}
int main()
{
freopen("heavypath.in","r",stdin);
freopen("heavypath.out","w",stdout);
read();
chains();
solve();
return 0;
}