#include <bits//stdc++.h>
using namespace std;
ifstream fin ("heavypath.in");
ofstream fout ("heavypath.out");
const int NMAX = 1e5;
int posCurr, n, m;
int v[NMAX + 2];
int aint[NMAX + 2];
int depth[NMAX + 2];
int parent[NMAX + 2];
int heavy[NMAX + 2];
int pos[NMAX + 2];
int head[NMAX + 2];
int viz[NMAX + 2];
vector <int> g[NMAX + 2];
int dfs (int node) {
int sz = 1, maxSize = 0;
viz[node] = 1;
for (int next : g[node]) {
if (!viz[next]) {
depth[next] = 1 + depth[node];
parent[next] = node;
int csz = dfs(next);
sz += csz;
if (maxSize < csz) {
maxSize = csz;
heavy[node] = next;
}
}
}
return sz;
}
void decompuse (int node, int sef) {
head[node] = sef;
pos[node] = ++posCurr;
viz[node] = 1;
if (!viz[heavy[node]] && heavy[node] != 0)
decompuse(heavy[node], sef);
for (int next : g[node])
if (!viz[next] && heavy[node] != next)
decompuse(next, next);
}
void update (int node, int from, int to, int pos, int x) {
if (from == to) {
aint[node] = x;
return ;
}
int mid = (from + to) >> 1;
if (x <= mid)
update (2 * node, from, mid, pos, x);
else
update (2 * node + 1, mid + 1, to, pos, x);
aint[node] = max(aint[2 * node], aint[2 * node + 1]);
}
int query (int node, int from, int to, int x, int y) {
if (from == x && y == to)
return aint[node];
int mid = (from + to) >> 1;
if (x > mid)
return query (2 * node + 1, mid + 1, to, x, y);
if (y <= mid)
return query (2 * node, from, mid, x, y);
return max(query(2 * node, from, mid, x, mid), query(2 * node + 1, mid + 1, to, mid + 1, y));
}
int value (int a, int b) {
if (a > b) swap(a, b);
return query (1, 1, n, a, b);
}
int solve (int a, int b) {
int max1 = 0;
for (; head[a] != head[b]; b = parent[head[b]]) {
if (depth[head[a]] > depth[head[b]])
swap(a, b);
max1 = max(max1, value(pos[head[b]], pos[b]));
}
if (depth[a] > depth[b])
swap(a, b);
max1 = max(max1, value(pos[a], pos[b]));
return max1;
}
int main() {
int i, tip, x, y;
fin >> n >> m;
for (i = 1; i <= n; ++i)
fin >> v[i];
for (i = 1; i < n; ++i) {
fin >> x >> y;
g[x].push_back(y);
g[y].push_back(x);
}
dfs(1);
for (i = 1; i <= n; ++i)
viz[i] = 0;
decompuse(1, 1);
for (i = 1; i <= n; ++i)
update(1, 1, n, i, v[i]);
while (m--) {
fin >> tip >> x >> y;
if (tip == 0)
update(1, 1, n, x, y);
else
fout << solve(x, y) << "\n";
}
return 0;
}