// Mihai Priboi
#include <stdio.h>
#include <vector>
using namespace std;
#define MAX_N 100'000
vector<int> graph[MAX_N];
int parent[MAX_N], depth[MAX_N], heavy[MAX_N], head[MAX_N], pos[MAX_N];
int aint[MAX_N * 2];
int v[MAX_N];
int n, current_pos;
int aint_get_max(int a, int b, int l, int r, int node) {
if(l == a && r == b)
return aint[node];
int leftChild, rightChild, middle;
middle = (r + l) / 2;
leftChild = node + 1;
rightChild = node + 2 * (middle - l + 1);
int mx = 0;
if(a <= middle)
mx = max(mx, aint_get_max(a, min(middle, b), l, middle, leftChild));
if(b > middle)
mx = max(mx, aint_get_max(max(middle + 1, a), b, middle + 1, r, rightChild));
return mx;
}
void aint_update(int l, int r, int node, int pos, int val) {
if(l == r) {
aint[node] = val;
return;
}
int leftChild, rightChild, middle;
middle = (r + l) / 2;
leftChild = node + 1;
rightChild = node + 2 * (middle - l + 1);
if(pos <= middle)
aint_update(l, middle, leftChild, pos, val);
else
aint_update(middle + 1, r, rightChild, pos, val);
aint[node] = max(aint[leftChild], aint[rightChild]);
}
int dfs(int node) {
int size = 1;
int max_size = 0;
heavy[node] = -1;
for(int v : graph[node]) {
if(v != parent[node]) {
parent[v] = node;
depth[v] = depth[node] + 1;
int v_size = dfs(v);
size += v_size;
if(v_size > max_size) {
max_size = v_size;
heavy[node] = v;
}
}
}
}
void decompose(int node, int h) {
head[node] = h;
pos[node] = current_pos++;
if(heavy[node] != -1)
decompose(heavy[node], h);
for(int v : graph[node])
if(v != parent[node] && v != heavy[node])
decompose(v, v);
}
int query(int a, int b) {
int res = 0;
while(head[a] != head[b]) {
if(depth[head[a]] > depth[head[b]])
swap(a, b);
res = max(res, aint_get_max(pos[head[b]], pos[b], 0, n - 1, 0));
b = parent[head[b]];
}
if(depth[a] > depth[b])
swap(a, b);
res = max(res, aint_get_max(pos[a], pos[b], 0, n - 1, 0));
}
int main() {
FILE *fin, *fout;
int m, i, x, y, t;
fin = fopen("heavypath.in", "r");
fout = fopen("heavypath.out", "w");
fscanf(fin, "%d%d", &n, &m);
for(i = 0; i < n; i++)
fscanf(fin, "%d", &v[i]);
for(i = 0; i < n - 1; i++) {
fscanf(fin, "%d%d", &x, &y);
x--, y--;
graph[x].push_back(y);
graph[y].push_back(x);
}
dfs(0);
current_pos = 0;
decompose(0, 0);
for(i = 0; i < n; i++)
aint_update(0, n - 1, 0, pos[i], v[i]);
for(i = 0; i < m; i++) {
fscanf(fin, "%d%d%d", &t, &x, &y);
if(t == 0)
aint_update(0, n - 1, 0, pos[x - 1], y);
else
fprintf(fout, "%d\n", query(x - 1, y - 1));
}
fclose(fin);
fclose(fout);
return 0;
}