#include <bits/stdc++.h>
#define int long long
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
int aint[400009], n, val[100009], poz[100009], nivel[100009], dim[100009], head[100009], q, lin[100009], cnt=0, tata[100009];
vector <int> v[100009];
int query (int nod, int st, int dr, int left, int right)
{
if (left>right)
swap (left, right);
if (st==left && dr==right)
return aint[nod];
int mij=(st+dr)/2;
if (right<=mij)
return query (2*nod, st, mij, left, right);
if (left>mij)
return query (2*nod+1, mij+1, dr, left, right);
else
return max (query(2*nod, st, mij, left, mij), query(2*nod+1, mij+1, dr, mij+1, right));
}
int query (int st, int dr)
{
return query (1, 1, n, st, dr);
}
void update (int nod, int st, int dr, int poz, int val)
{
if (st==dr)
aint[nod]=val;
else
{
int mij=(st+dr)/2;
if (poz<=mij)
update (2*nod, st, mij, poz, val);
else
update (2*nod+1, mij+1, dr, poz, val);
aint[nod]=max (aint[2*nod], aint[2*nod+1]);
}
}
void update (int poz, int val)
{
update (1, 1, n, poz, val);
}
void dfs (int nod, int tata1)
{
dim[nod]++;
tata[nod]=tata1;
for (auto y:v[nod])
{
if (y!=tata1)
{
nivel[y]=nivel[nod]+1;
dfs (y, nod);
dim[nod]+=dim[y];
}
}
}
void dfs_greu (int nod, int tata1)
{
lin[++cnt]=nod;
poz[nod]=cnt;
int heavy=0;
for (auto y:v[nod])
{
if (y!=tata1 && dim[y]>dim[heavy])
heavy=y;
}
if (!heavy)
return;
head[heavy]=head[nod];
dfs_greu (heavy, nod);
for (auto y:v[nod])
{
if (y!=tata1 && y!=heavy)
dfs_greu (y, nod);
}
}
int query_greu (int x, int y)
{
//cout << x << ' ' << y << '\n';
int sol=0;
if (head[x]==head[y])
sol=query (poz[x], poz[y]);
else
{
int t1=head[x], t2=head[y];
if (nivel[t1]>nivel[t2])
sol=query (poz[x], poz[t1]), x=tata[t1];
else
sol=query (poz[y], poz[t2]), y=tata[t2];
sol=max (sol, query_greu(x, y));
}
return sol;
}
signed main ()
{
f >>n >> q;
for (int i=1; i<=n; i++)
f >> val[i], head[i]=i;
for (int i=1; i<n; i++)
{
int x, y;
f >> x >> y;
v[x].push_back(y);
v[y].push_back(x);
}
dfs (1, 0);
dfs_greu (1, 0);
for (int i=1; i<=n; i++)
update (i, val[i]);
//cout << head[3] << ' ';
while (q--)
{
//cout << '*';
int tip;
f >> tip;
int x, y;
f >> x >> y;
if (!tip)
update (poz[x], y);
else
g << query_greu (x, y) << '\n';
}
}