#include <vector>
#include <algorithm>
#include <cstdio>
using namespace std;
const int MAX_N = 100002;
int N, M, nP;
int F[MAX_N], Lv[MAX_N], W[MAX_N], val[MAX_N];
pair < int, int > pos[MAX_N];
vector < int > v[MAX_N], Aint[MAX_N], Path[MAX_N];
bool vis[MAX_N];
void DFS(int x) {
vis[x] = 1;
int z = 0;
for(int i = 0; i < (int) v[x].size(); ++i) {
int y = v[x][i];
if(vis[y])
continue;
F[y] = x;
Lv[y] = Lv[x] + 1;
DFS(y);
if(z == 0 || W[y] > W[z])
z = y;
}
if(z == 0) {
++nP;
Path[nP].push_back(0);
Path[nP].push_back(x);
pos[x].first = nP;
W[x] = 1;
}
else {
W[x] = W[z] + 1;
Path[pos[z].first].push_back(x);
pos[x].first = pos[z].first;
}
}
void build(int ind, int node, int left, int right) {
if(left == right)
Aint[ind][node] = val[Path[ind][left]];
else {
int ls = 2 * node, rs = 2 * node + 1, m = (left + right) / 2;
build(ind, ls, left, m);
build(ind, rs, m + 1, right);
Aint[ind][node] = max(Aint[ind][ls], Aint[ind][rs]);
}
}
void makePaths() {
F[1] = 1;
Lv[1] = 1;
DFS(1);
for(int i = 1; i <= nP; ++i) {
int n = Path[i].size() - 1;
for(int j = 1, k = n; j < k; ++j, --k)
swap(Path[i][j], Path[i][k]);
for(int j = 1; j <= n; ++j)
pos[Path[i][j]].second = j;
for(int j = 0; j <= 4 * n; ++j)
Aint[i].push_back(0);
build(i, 1, 1, n);
}
}
int update(int ind, int node, int left, int right, int x, int y) {
if(left == right)
Aint[ind][node] = y;
else {
int ls = 2 * node, rs = 2 * node + 1, m = (left + right) / 2;
if(x <= m)
update(ind, ls, left, m, x, y);
else update(ind, rs, m + 1, right, x, y);
Aint[ind][node] = max(Aint[ind][ls], Aint[ind][rs]);
}
}
int query(int ind, int node, int left, int right, int x, int y) {
int ret = 0;
if(x <= left && right <= y)
ret = Aint[ind][node];
else {
int ls = 2 * node, rs = 2 * node + 1, m = (left + right) / 2;
if(x <= m)
ret = query(ind, ls, left, m, x, y);
if(y > m)
ret = max(ret, query(ind, rs, m + 1, right, x, y));
}
return ret;
}
int main() {
freopen("heavypath.in", "r", stdin);
freopen("heavypath.out", "w", stdout);
scanf("%d %d", &N, &M);
for(int i = 1; i <= N; ++i)
scanf("%d", &val[i]);
for(int i = 1; i < N; ++i) {
int x, y;
scanf("%d %d", &x, &y);
v[x].push_back(y);
v[y].push_back(x);
}
makePaths();
for(int q = 1; q <= M; ++q) {
int t, x, y;
scanf("%d %d %d", &t, &x, &y);
if(t == 0) {
int ind = pos[x].first, p = pos[x].second;
update(ind, 1, 1, Path[ind].size() - 1, p, y);
}
else {
int ans = 0;
bool ok = 1;
while(ok) {
if(pos[x].first == pos[y].first) {
if(Lv[x] > Lv[y])
swap(x, y);
int ind = pos[x].first, px = pos[x].second, py = pos[y].second;
ans = max(ans, query(ind, 1, 1, Path[ind].size() - 1, px, py));
ok = 0;
}
else {
int indx = pos[x].first, indy = pos[y].first, fx = 0, fy = 0;
fx = F[Path[indx][1]];
fy = F[Path[indy][1]];
if(Lv[fx] < Lv[fy]) {
swap(x, y);
swap(indx, indy);
swap(fx, fy);
}
int px = pos[x].second, n = Path[indx].size() - 1;
ans = max(ans, query(indx, 1, 1, n, 1, px));
x = fx;
}
}
printf("%d\n", ans);
}
}
return 0;
}