#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int NMAX = 100005;
const int INF = 0x7fffffff;
int valNod[NMAX];
int hNod[NMAX];
int size[NMAX];
int heavy[NMAX];
int father[NMAX];
int aint[4 * NMAX];
int position[NMAX];
bool visited[NMAX];
int chainHead[NMAX];
vector <int> g[NMAX];
vector <int> heavyTransversal;
int n, m;
void dfsSize(int u) {
visited[u] = 1;
size[u] = 1;
for(auto v : g[u]) {
if(!visited[v]) {
father[v] = u;
dfsSize(v);
size[u] += size[v];
if(size[v] > size[heavy[u]]) {
heavy[u] = v;
}
}
}
}
void dfsHeavy(int u, int h, int head) {
visited[u] = 1;
hNod[u] = h;
chainHead[u] = head;
position[u] = (int)heavyTransversal.size();
heavyTransversal.push_back(valNod[u]);
if(heavy[u] != 0) {
dfsHeavy(heavy[u], h + 1, head);
for(auto v : g[u]) {
if(!visited[v]) {
dfsHeavy(v, h + 1, v);
}
}
}
}
void update(int nod, int st, int dr, int i, int val) {
if(st == dr) {
aint[nod] = val;
}
else {
int mij = (st + dr) / 2;
if(i <= mij) {
update(2 * nod, st, mij, i, val);
}
else {
update(2 * nod + 1, mij + 1, dr, i, val);
}
aint[nod] = max(aint[2 * nod], aint[2 * nod + 1]);
}
}
int query(int nod, int st, int dr, int x, int y) {
if(x <= st && dr <= y) {
return aint[nod];
}
else {
int sol = -INF, mij = (st + dr) / 2;
if(x <= mij) {
sol = max(sol, query(2 * nod, st, mij, x, y));
}
if(mij + 1 <= y) {
sol = max(sol, query(2 * nod + 1, mij + 1, dr, x, y));
}
return sol;
}
}
void update(int i, int val) {
update(1, 1, n, i, val);
}
int query(int x, int y) {
return query(1, 1, n, x, y);
}
int maxPath(int u, int v) {
if(chainHead[u] == chainHead[v]) {
if(position[u] < position[v]) {
return query(position[u], position[v]);
}
else {
return query(position[v], position[u]);
}
}
else if(hNod[chainHead[u]] > hNod[chainHead[v]]) {
return max(maxPath(father[chainHead[u]], v), query(position[chainHead[u]], position[u]));
}
else {
return max(maxPath(u, father[chainHead[v]]), query(position[chainHead[v]], position[v]));
}
}
int main() {
freopen("heavypath.in", "r", stdin);
freopen("heavypath.out", "w", stdout);
scanf("%d%d", &n, &m);
size[0] = 0;
for(int i = 1; i <= n; i++) {
scanf("%d", &valNod[i]);
visited[i] = 0;
heavy[i] = 0;
}
for(int i = 1; i < n; i++) {
int x, y;
scanf("%d%d", &x, &y);
g[x].push_back(y);
g[y].push_back(x);
}
heavyTransversal.push_back(0);
dfsSize(1);
for(int i = 1; i <= n; i++) {
visited[i] = 0;
}
father[1] = 0;
hNod[0] = 0;
dfsHeavy(1, 1, 1);
for(int i = 1; i <= n; i++) {
update(i, heavyTransversal[i]);
}
for(int i = 1; i <= m; i++) {
int t, x, y;
scanf("%d%d%d", &t, &x, &y);
if(t == 0) {
update(position[x], y);
}
else if(t == 1) {
printf("%d\n", maxPath(x, y));
}
}
return 0;
}