#include <bits/stdc++.h>
#define Nmax 100005
using namespace std;
ifstream fin ("heavypath.in");
ofstream fout ("heavypath.out");
int n, q, aux[Nmax], a[Nmax], poz[Nmax], top[Nmax], t[Nmax], d[Nmax], sz[Nmax], aint[4*Nmax];
vector <int> v[Nmax];
void dfs(int x)
{
sz[x]=1;
for(auto it:v[x])
if(t[x]!=it)
{
t[it]=x;
d[it]=d[x]+1;
dfs(it);
sz[x]+=sz[it];
}
}
void descompunere(int x, int h)
{
top[x]=h;
a[++n]=aux[x];
poz[x]=n;
int maxx=0, heavy=-1;
for(auto it:v[x])
if(t[x]!=it && sz[it]>maxx)
{
maxx=sz[it];
heavy=it;
}
if(heavy!=-1)
descompunere(heavy, h);
for(auto it:v[x])
if(t[x]!=it && it!=heavy)
descompunere(it, it);
}
void build(int nod, int st, int dr)
{
if(st==dr)
{
aint[nod]=a[st];
return;
}
int mij=(st+dr)/2;
build(nod*2, st, mij);
build(nod*2+1, mij+1, dr);
aint[nod]=max(aint[nod*2], aint[nod*2+1]);
}
void update(int nod, int st, int dr, int poz, int val)
{
if(st==dr)
{
aint[nod]=val;
return;
}
int mij=(st+dr)/2;
if(poz<=mij)
update(nod*2, st, mij, poz, val);
else update(nod*2+1, mij+1, dr, poz, val);
aint[nod]=max(aint[nod*2], aint[nod*2+1]);
}
int maxim(int nod, int st, int dr, int a, int b)
{
if(a<=st && dr<=b)
return aint[nod];
int mij=(st+dr)/2, maxx=0;
if(a<=mij)
maxx=max(maxx, maxim(nod*2, st, mij, a, b));
if(mij+1<=b)
maxx=max(maxx, maxim(nod*2+1, mij+1, dr, a, b));
return maxx;
}
int raspuns(int x, int y)
{
int maxx=0;
while(top[x]!=top[y])
{
if(d[top[x]]>d[top[y]])
swap(x, y);
maxx=max(maxx, maxim(1, 1, n, poz[top[y]], poz[y]));
y=t[top[y]];
}
if(d[x]>d[y])
swap(x, y);
maxx=max(maxx, maxim(1, 1, n, poz[x], poz[y]));
return maxx;
}
int main()
{
fin >> n >> q;
for(int i=1;i<=n;i++)
fin >> aux[i];
for(int i=1;i<n;i++)
{
int x, y;
fin >> x >> y;
v[x].push_back(y);
v[y].push_back(x);
}
n=0;
dfs(1);
descompunere(1, 1);
build(1, 1, n);
while(q--)
{
int t, x, y;
fin >> t >> x >> y;
if(t==0)
update(1, 1, n, poz[x], y);
else
fout << raspuns(x, y) << '\n';
}
return 0;
}