#include <bits/stdc++.h>
using namespace std;
#define eb emplace_back
const string TASK("heavypath");
ifstream fin(TASK + ".in");
ofstream fout(TASK + ".out");
struct SegmentTree {
vector<int> tree; int n = 0;
void init(int sz) {n = sz; tree = vector<int> (4 * n + 5);}
int query(int l, int r) {return Query(1, 1, n, l, r);}
void update(int p, int v) {Update(1, 1, n, p, v);}
void Update(int x, int l, int r, int p, int v) {
if (l == r) {tree[x] = v; return;}
int mid = (l + r) / 2;
if (p <= mid) Update(2*x, l, mid, p, v);
else Update(2*x+1, mid+1, r, p, v);
tree[x] = max(tree[2*x], tree[2*x+1]);
}
int Query(int x, int l, int r, int ql, int qr) {
if (r < ql || qr < l) return 0;
if (ql <= l && r <= qr) return tree[x];
int mid = (l + r) / 2;
return max(Query(2*x,l,mid,ql,qr),Query(2*x+1,mid+1,r,ql,qr));
}
};
const int N = 1e5 + 5;
int what[N], where[N];
SegmentTree chain[N];
int n, q, val[N], sz[N], heavy_son[N], paths = 1;
int chain_size[N], depth[N], start[N], up[N];
vector<int> adj[N];
void dfssz(int u, int parent) {
sz[u] = 1;
depth[u] = depth[parent] + 1;
up[u] = parent;
int mx = 0;
for (auto v : adj[u])
if (v != parent) {
dfssz(v, u);
sz[u] += sz[v];
if (!mx || sz[mx] < sz[v])
mx = v;
}
heavy_son[u] = mx;
}
void dfspath(int u, int parent, int path, int pos) {
what[u] = path;
where[u] = pos;
if (pos == 1)
start[path] = u;
++chain_size[path];
for (auto v : adj[u]) {
if (v == parent) continue;
if (v == heavy_son[u])
dfspath(v, u, path, pos + 1);
else dfspath(v, u, ++paths, 1);
}
}
int hp_query(int u, int v) {
//cout << u << ' ' << v << '\n';
if (what[u] == what[v])
return chain[what[u]].query(min(where[u],where[v]),max(where[u],where[v]));
if (depth[start[what[u]]] < depth[start[what[v]]])
swap(u, v);
int wu = what[u];
return max(chain[wu].query(where[start[wu]], where[u]), hp_query(up[start[wu]], v));
}
int main() {
fin >> n >> q;
for (int i = 1; i <= n; ++i)
fin >> val[i];
for (int u, v, i = 1; i < n; ++i) {
fin >> u >> v;
adj[u].eb(v); adj[v].eb(u);
}
dfssz(1, 0);
dfspath(1, 0, 1, 1);
//for (int i = 1; i <= n; ++i)
// fout << i << ' ' << what[i] << ' ' << where[i] << '\n';
for (int i = 1; i <= n; ++i) {
if (!chain[what[i]].n)
chain[what[i]].init(chain_size[what[i]]);
chain[what[i]].update(where[i], val[i]);
}
while (q--) {
int x, y, type;
fin >> type >> x >> y;
if (type == 0)
chain[what[x]].update(where[x], y);
else fout << hp_query(x, y) << '\n';
}
}