/// Preset de infoarena
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
const int maxN = 200005;
int n, q, val[maxN];
int sz[maxN], p[maxN], cnt, ind[maxN], depth[maxN], cap[maxN], aint[4 * maxN], v[maxN];
vector <int> G[maxN];
void dfs(int nod, int tata)
{
p[nod] = tata;
depth[nod] = depth[tata] + 1;
sz[nod] = 1;
cap[nod] = nod;
for(int vecin : G[nod])
{
if(vecin == tata)
continue;
dfs(vecin, nod);
sz[nod] += sz[vecin];
}
}
void dfs_heavy(int nod)
{
ind[nod] = ++cnt;
int max_sz = -1, nxt = -1;
for(int vecin : G[nod])
{
if(vecin == p[nod])
continue;
if(sz[vecin] > max_sz)
{
max_sz = sz[vecin];
nxt = vecin;
}
}
if(nxt == -1)
return;
cap[nxt] = cap[nod];
dfs_heavy(nxt);
for(int vecin : G[nod])
if(vecin != p[nod] && vecin != nxt)
dfs_heavy(vecin);
}
void init_aint(int nod, int st, int dr)
{
if(st == dr)
{
aint[nod] = v[st];
return;
}
int med = (st + dr) / 2;
init_aint(2 * nod, st, med);
init_aint(2 * nod + 1, med + 1, dr);
aint[nod] = max(aint[2 * nod], aint[2 * nod + 1]);
}
void update(int nod, int st, int dr, int upoz, int uval)
{
if(st == dr)
{
aint[nod] = uval;
return;
}
int med = (st + dr) / 2;
if(upoz <= med)
update(2 * nod, st, med, upoz, uval);
if(med + 1 <= upoz)
update(2 * nod + 1, med + 1, dr, upoz, uval);
aint[nod] = max(aint[2 * nod], aint[2 * nod + 1]);
}
int query(int nod, int st, int dr, int qst, int qdr)
{
if(qst <= st && dr <= qdr)
return aint[nod];
int med = (st + dr) / 2, aux = -1;
if(qst <= med)
aux = max(aux, query(2 * nod, st, med, qst, qdr));
if(med + 1 <= qdr)
aux = max(aux, query(2 * nod + 1, med + 1, dr, qst, qdr));
return aux;
}
int get_ans(int a, int b)
{
if(cap[a] == cap[b])
{
if(ind[a] > ind[b])
swap(a, b);
return query(1, 1, n, ind[a], ind[b]);
}
if(depth[cap[a]] < depth[cap[b]])
swap(a, b);
return max(query(1, 1, n, ind[cap[a]], ind[a]), get_ans(p[cap[a]], b));
}
int main()
{
fin >> n >> q;
for(int i = 1; i <= n; i++)
fin >> val[i];
for(int i = 1; i < n; i++)
{
int x, y;
fin >> x >> y;
G[x].push_back(y);
G[y].push_back(x);
}
dfs(1, 0);
dfs_heavy(1);
for(int i = 1; i <= n; i++)
v[ind[i]] = val[i];
init_aint(1, 1, n);
for(int i = 1; i <= q; i++)
{
int op, x, y;
fin >> op >> x >> y;
if(op == 0)
update(1, 1, n, ind[x], y);
if(op == 1)
{
int ans = get_ans(x, y);
fout << ans << '\n';
}
}
return 0;