#include <stdio.h>
#include <algorithm>
#include <vector>
#define NMAX 100005
#define LMAX 400005
#define INF 2000000000
#define pb push_back
using namespace std;
int n,m,val[NMAX],cnt[NMAX],best_n[NMAX],nrc,which[NMAX],poz[NMAX],poz_i[NMAX];
int dec[NMAX],arb[LMAX],ind,dad[NMAX],lvl[NMAX],lst,ldr;
vector <int> A[NMAX],B[NMAX];
bool viz[NMAX];
void read()
{
scanf("%d%d",&n,&m);
int i,x,y;
for (i=1; i<=n; i++)
scanf("%d",&val[i]);
for (i=1; i<n; i++)
{
scanf("%d%d",&x,&y);
A[x].pb(y); A[y].pb(x);
}
}
void dfs(int nod)
{
viz[nod]=1; cnt[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;
dfs(vec);
cnt[nod]+=cnt[vec];
if (cnt[vec]>cnt[best_n[nod]])
best_n[nod]=vec;
}
}
if (cnt[nod]==1)
{
B[++nrc].pb(nod); which[nod]=nrc;
return ;
}
B[which[best_n[nod]]].pb(nod); which[nod]=which[best_n[nod]];
for (i=0; i<A[nod].size(); i++)
{
vec=A[nod][i];
if (lvl[vec]>lvl[nod] && which[nod]!=which[vec])
dad[which[vec]]=nod;
}
}
inline int max(int x,int y)
{
return x>y ? x : y;
}
void cstr(int st,int dr,int nod,int decalaj)
{
if (st==dr)
{
poz_i[B[ind][st-1]]=nod;
arb[nod+decalaj]=val[B[ind][st-1]];
return ;
}
int mij=(st+dr)/2;
cstr(st,mij,nod*2,decalaj);
cstr(mij+1,dr,nod*2+1,decalaj);
arb[nod+decalaj]=max(arb[nod*2+decalaj],arb[nod*2+1+decalaj]);
}
void chains()
{
dfs(1);
int i,j;
for (i=1; i<=nrc; i++)
reverse(B[i].begin(),B[i].end());
for (i=1; i<=nrc; i++)
{
dec[i]=dec[i-1]+4*B[i].size();
for (j=0; j<B[i].size(); j++)
poz[B[i][j]]=j+1;
ind=i;
cstr(1,B[i].size(),1,dec[i-1]);
}
}
void update(int nod,int v,int decalaj)
{
nod=poz_i[nod];
arb[nod+decalaj]=v;
for (nod/=2 ; nod ; nod/=2)
arb[nod+decalaj]=max(arb[nod*2+decalaj],arb[nod*2+1+decalaj]);
}
int find(int st,int dr,int nod,int decalaj)
{
if (dr<lst || ldr<st)
return -INF;
if (lst<=st && dr<=ldr)
return arb[nod+decalaj];
int mij=(st+dr)/2;
return max(find(st,mij,nod*2,decalaj),find(mij+1,dr,nod*2+1,decalaj));
}
void solve()
{
int i,tip,x,y,z,rez;
for (i=1; i<=m; i++)
{
scanf("%d%d%d",&tip,&x,&y);
if (tip==0)
update(x,y,dec[which[x]-1]);
else
{
rez=0;
while (which[x]!=which[y])
{
if (lvl[dad[which[x]]]<lvl[dad[which[y]]])
z=x,x=y,y=z;
lst=1; ldr=poz[x];
rez=max(rez,find(1,B[which[x]].size(),1,dec[which[x]-1]));
x=dad[which[x]];
}
if (lvl[x]>lvl[y])
z=x,x=y,y=z;
lst=poz[x]; ldr=poz[y];
rez=max(rez,find(1,B[which[x]].size(),1,dec[which[x]-1]));
printf("%d\n",rez);
}
}
}
int main()
{
freopen("heavypath.in","r",stdin);
freopen("heavypath.out","w",stdout);
read();
chains();
solve();
return 0;
}