#include <bits/stdc++.h>
using namespace std;
int sz[100010],tata[100010],niv[100010],first[100010],a[100010],arb[400010],l,nxt[100010];
vector<int> v[100010];
void dfs(int nod,int tat)
{
tata[nod]=tat;
sz[nod]=1;
if(v[nod].size()>1 && v[nod][0]==tat) swap(v[nod][0],v[nod][1]);
for(int i=0;i<v[nod].size();i++)
{
int vec=v[nod][i];
if(vec==tat) continue;
niv[vec]=niv[nod]+1;
dfs(vec,nod);
sz[nod]+=sz[vec];
if(sz[vec]>sz[v[nod][0]]) swap(v[nod][0],v[nod][i]);
}
}
void dfs1(int nod)
{
first[nod]=++l;
for(int i=0;i<v[nod].size();i++)
{
int vec=v[nod][i];
if(vec==tata[nod]) continue;
if(i==0) nxt[vec]=nxt[nod];
else nxt[vec]=vec;
dfs1(vec);
}
}
void update(int nod,int st,int dr,int poz,int s)
{
if(st==dr) arb[nod]=s;
else
{
int mid=(st+dr)/2;
if(poz<=mid) update(nod*2,st,mid,poz,s);
else update(nod*2+1,mid+1,dr,poz,s);
arb[nod]=max(arb[nod*2],arb[nod*2+1]);
}
}
int query(int nod,int st,int dr,int left,int right)
{
if(left<=st && dr<=right) return arb[nod];
int mid=(st+dr)/2,s=0;
if(left<=mid) s=query(nod*2,st,mid,left,right);
if(mid<right) s=max(s,query(nod*2+1,mid+1,dr,left,right));
return s;
}
int go(int x,int y)
{
int s=0;
while(nxt[x]!=nxt[y])
{
if(niv[nxt[x]]<niv[nxt[y]]) swap(x,y);
s=max(s,query(1,1,l,first[nxt[x]],first[x]));
x=tata[nxt[x]];
}
if(niv[x]<niv[y]) swap(x,y);
return max(s,query(1,1,l,first[y],first[x]));
}
int main()
{
freopen("heavypath.in","r",stdin);
freopen("heavypath.out","w",stdout);
int n,m,x,y,t;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
nxt[1]=1;
dfs(1,0);
dfs1(1);
for(int i=1;i<=n;i++)
update(1,1,n,first[i],a[i]);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&t,&x,&y);
if(!t) update(1,1,n,first[x],y);
else printf("%d\n",go(x,y));
}
return 0;
}