#include <bits/stdc++.h>
using namespace std;
const int NMAX = 100010;
class Aint
{
vector <int> aint;
int n, val, poz, l, r;
void update(int nod, int st, int dr) {
if (st > poz || dr < poz)
return;
aint[nod] = val;
if (st != dr) {
update(2 * nod, st, (st + dr) / 2);
update(2 * nod + 1, (st + dr) / 2 + 1, dr);
aint[nod] = max(aint[2 * nod], aint[2 * nod + 1]);
}
}
int query(int nod, int st, int dr) {
if (st > r || dr < l)
return 0;
if (l <= st && r >= dr)
return aint[nod];
return max(query(2 * nod, st, (st + dr) / 2),
query(2 * nod + 1, (st + dr) / 2 + 1, dr));
}
public:
Aint(int n) : n(n), aint(vector <int> (4 * n)) { }
int query(int st, int dr) {
l = st, r = dr;
return query(1, 1, n);
}
void update(int p, int v) {
poz = p, val = v;
update(1, 1, n);
}
};
struct HeavyPath {
vector <int> adia[NMAX];
int h[NMAX], tata[NMAX], jump[NMAX], g[NMAX];
int id[NMAX], cnt = 0;
int calc_g(int nod) {
g[nod] = 1;
if (tata[nod])
adia[nod].erase(find(adia[nod].begin(), adia[nod].end(), tata[nod]));
for (auto i : adia[nod]) {
tata[i] = nod, h[i] = 1 + h[nod];
g[nod] += calc_g(i);
}
return g[nod];
}
void calc_jump(int nod, int jmp) {
jump[nod] = jmp;
id[nod] = ++cnt;
if (adia[nod].empty())
return;
pair <int, int> best = { -1, -1 };
for (auto i : adia[nod])
best = max(best, { g[i], i });
calc_jump(best.second, jmp);
for (auto i : adia[nod])
if (i != best.second)
calc_jump(i, i);
}
vector <pair <int, int>> get_intervs(int a, int b)
{
vector <pair <int, int>> ans;
while (jump[a] != jump[b]) {
if (h[jump[a]] < h[jump[b]])
swap(a, b);
ans.push_back({ id[jump[a]], id[a] });
a = tata[jump[a]];
}
if (h[a] < h[b])
swap(a, b);
ans.push_back({ id[b], id[a] });
return ans;
}
};
int v[NMAX];
int main()
{
ifstream in("heavypath.in");
ofstream out("heavypath.out");
int n, m, a, b;
in >> n >> m;
HeavyPath hp;
Aint aint(n + 1);
for (int i(1); i <= n; i++)
in >> v[i];
for (int i(1); i < n; i++) {
in >> a >> b;
hp.adia[a].push_back(b);
hp.adia[b].push_back(a);
}
hp.calc_g(1);
hp.calc_jump(1, 1);
for (int i(1); i <= n; i++)
aint.update(hp.id[i], v[i]);
while (m--) {
int t;
in >> t >> a >> b;
if (t == 1) {
auto x = hp.get_intervs(a, b);
int best(0);
for (auto i : x)
best = max(best, aint.query(i.first, i.second));
out << best << '\n';
}
else {
aint.update(hp.id[a], b);
}
}
return 0;
}