#include <stdio.h>
#include <vector>
#include <algorithm>
#define nmax 100010
using namespace std;
int n,m,tip,x,y,b;
int v[nmax],hight[nmax],w[nmax];
int szbucket[nmax],bucket[nmax],psbucket[nmax],tata[nmax];
vector <int> g[nmax],hp[nmax];
void dfs1(int nod,int dad)
{
w[nod]=1;
for (int i=0;i<(int)g[nod].size();i++)
if (g[nod][i]!=dad) {
hight[g[nod][i]]=hight[nod]+1;
dfs1(g[nod][i],nod);
w[nod]=w[nod]+w[g[nod][i]];
}
}
void dfs2(int nod,int dad,int nrb)
{
szbucket[nrb]++;
bucket[nod]=nrb;
psbucket[nod]=szbucket[nrb];
int mx=0;
for (int i=0;i<(int)g[nod].size();i++)
if (w[mx]<w[g[nod][i]] && g[nod][i]!=dad) mx=g[nod][i];
if (mx==0) return;
dfs2(mx,nod,nrb);
for (int i=0;i<(int)g[nod].size();i++)
if (g[nod][i]!=dad && g[nod][i]!=mx) {
b++; tata[b]=nod;
dfs2(g[nod][i],nod,b);
}
}
void update(int nod,int st,int dr,int pos,int val,vector <int> &t)
{
if (st==dr) { t[nod]=val; return; } else
{
int m=(st+dr)/2;
if (pos<=m) update(nod*2,st,m,pos,val,t); else
update(nod*2+1,m+1,dr,pos,val,t);
t[nod]=max(t[nod*2],t[nod*2+1]);
}
}
int query(int nod,int st,int dr,int x,int y,vector <int> &t)
{
if (st>=x && dr<=y) return t[nod]; else
{
int m=(st+dr)/2; int csol=0;
if (x<=m) csol=max(csol,query(nod*2,st,m,x,y,t));
if (y>m) csol=max(csol,query(nod*2+1,m+1,dr,x,y,t));
return csol;
}
}
int main()
{
freopen("heavypath.in","r",stdin);
freopen("heavypath.out","w",stdout);
scanf("%d %d",&n,&m);
for (int i=1;i<=n;i++) scanf("%d",&v[i]);
for (int i=1;i<=n-1;i++) {
scanf("%d %d",&x,&y);
g[x].push_back(y); g[y].push_back(x);
}
b=1;
dfs1(1,0);
dfs2(1,0,1);
for (int i=1;i<=b;i++) hp[i].resize(szbucket[i]*4);
for (int i=1;i<=n;i++) update(1,1,szbucket[bucket[i]],psbucket[i],v[i],hp[bucket[i]]);
//printtree(1,1,szbucket[1],hp[1]);
for (int i=1;i<=m;i++) {
scanf("%d %d %d",&tip,&x,&y);
if (tip==0) update(1,1,szbucket[bucket[x]],psbucket[x],y,hp[bucket[x]]); else
{
int sol=0;
while (bucket[x]!=bucket[y]) {
if (hight[tata[bucket[x]]]<hight[tata[bucket[y]]]) swap(x,y);
sol=max(sol,query(1,1,szbucket[bucket[x]],1,psbucket[x],hp[bucket[x]]));
x=tata[bucket[x]];
}
if (psbucket[x]>psbucket[y]) swap(x,y);
sol=max(sol,query(1,1,szbucket[bucket[x]],psbucket[x],psbucket[y],hp[bucket[x]]));
printf("%d\n",sol);
}
}
return 0;
}