#include <bits/stdc++.h>
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
const int NMAX = 100005;
struct SegTree {
vector<int> aint;
vector<int> vals;
int n;
void build(int nod, int st, int dr)
{
if(st == dr)
{
aint[nod] = vals[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]);
}
SegTree()
{
}
SegTree(vector<int> nodes)
{
n = nodes.size();
vals.resize(n + 1);
for(int i = 1; i <= n; i++)
vals[i] = nodes[i - 1];
aint.resize(4 * n + 1);
build(1, 1, n);
}
int query(int nod, int st, int dr, int l, int r)
{
if(l <= st && dr <= r)
return aint[nod];
int mij = (st + dr) / 2;
int v1 = 0, v2 = 0;
if(l <= mij)
v1 = query(nod * 2, st, mij, l, r);
if(mij < r)
v2 = query(nod * 2 + 1, mij + 1, dr, l, r);
return max(v1, v2);
}
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 n, q;
vector<int> g[NMAX];
int v[NMAX];
int lvl[NMAX];
int sz[NMAX];
int maxSon[NMAX];
int dad[NMAX];
int id[NMAX];
int pos[NMAX];
int csz[NMAX];
int chainBoss[NMAX];
int cnt;
vector<int> nodes[NMAX];
SegTree chain[NMAX];
void getW(int nod, int tata)
{
dad[nod] = tata;
lvl[nod] = lvl[tata] + 1;
sz[nod] = 1;
for(auto it : g[nod])
if(it != tata)
{
getW(it, nod);
sz[nod] += sz[it];
if(sz[it] > sz[maxSon[nod]])
maxSon[nod] = it;
}
}
void dfs(int nod)
{
id[nod] = cnt;
nodes[cnt].push_back(v[nod]);
pos[nod] = ++csz[cnt];
if(!maxSon[nod])
{
chain[cnt] = SegTree(nodes[cnt]);
return;
}
dfs(maxSon[nod]);
for(auto it : g[nod])
if(it != dad[nod] && it != maxSon[nod])
{
chainBoss[++cnt] = it;
dfs(it);
}
}
int query(int x, int y)
{
if(id[x] == id[y])
return chain[id[x]].query(1, 1, csz[id[x]], min(pos[x], pos[y]), max(pos[x], pos[y]));
if(lvl[chainBoss[id[x]]] < lvl[chainBoss[id[y]]])
swap(x, y);
return max(chain[id[x]].query(1, 1, csz[id[x]], 1, pos[x]), query(dad[chainBoss[id[x]]], y));
}
void update(int x, int y)
{
chain[id[x]].update(1, 1, csz[id[x]], pos[x], y);
}
void solve()
{
fin >> n >> q;
for(int i = 1; i <= n; i++)
fin >> v[i];
for(int i = 1; i < n; i++)
{
int u, v;
fin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
getW(1, 0);
cnt = 1;
chainBoss[1] = 1;
dfs(1);
while(q--)
{
int tip, x, y;
fin >> tip >> x >> y;
if(tip == 0)
update(x, y);
else fout << query(x, y) << '\n';
}
}
int main()
{
solve();
return 0;
}