#include <bits/stdc++.h>
#define DIM 100001
#define time eiuhf
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
vector <int> G[DIM];
int wmt[4 * DIM];
int v[DIM], wmt_pos[DIM], father[DIM], depth[DIM], nodes[DIM], heavy_path[DIM], pos[DIM], chain[DIM], leader[DIM];
int time, n, i, m, Q, x, y, nr_chain, task;
void Build(int node, int st, int dr){
if(st == dr)
wmt[node] = v[wmt_pos[st]];
else {
int mij = (st + dr) >> 1;
Build(node << 1, st, mij);
Build(node << 1 | 1, mij + 1, dr);
wmt[node] = max(wmt[node << 1], wmt[node << 1 | 1]);
}
}
void Update(int node, int st, int dr, int a, int b){
if(st == dr)
wmt[node] = b;
else {
int mij = (st + dr) >> 1;
if(a <= mij)
Update(node << 1, st, mij, a, b);
else Update(node << 1 | 1, mij + 1, dr, a, b);
wmt[node] = max(wmt[node << 1], wmt[node << 1 | 1]);
}
}
int Query(int node, int st, int dr, int a, int b){
if(dr < a || st > b)
return 0;
if(st >= a && dr <= b)
return wmt[node];
else {
int mij = (st + dr) >> 1;
int ok1 = Query(node << 1, st, mij, a, b);
int ok2 = Query(node << 1 | 1, mij + 1, dr, a, b);
return max(ok1, ok2);
}
}
void dfs(int node, int mother){
father[node] = mother;
depth[node] = depth[father[node]] + 1;
nodes[node] = 1;
for(auto k : G[node]){
if(!depth[k]){
dfs(k, node);
if(nodes[heavy_path[node]] < nodes[k])
heavy_path[node] = k;
nodes[node] += nodes[k];
}
}
}
void decompose(int node, int mother){
++time;
wmt_pos[time] = node;
pos[node] = time;
if(heavy_path[mother] != node){
++nr_chain;
leader[nr_chain] = node;
chain[node] = nr_chain;
}
else chain[node] = chain[mother];
if(heavy_path[node])
decompose(heavy_path[node], node);
for(auto k : G[node])
if(k != mother && k != heavy_path[node])
decompose(k, node);
}
int solve(int x, int y){
int answer = 0;
while(chain[x] != chain[y]){
if(depth[leader[chain[x]]] < depth[leader[chain[y]]]){
answer = max(answer, Query(1, 1, n, pos[leader[chain[y]]], pos[y]));
y = father[leader[chain[y]]];
}
else {
answer = max(answer, Query(1, 1, n, pos[leader[chain[x]]], pos[x]));
x = father[leader[chain[x]]];
}
}
answer = max(answer, Query(1, 1, n, min(pos[x], pos[y]), max(pos[x], pos[y])));
return answer;
}
int main(){
fin >> n >> Q;
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, 0);
decompose(1, 0);
Build(1, 1, n);
while(Q--){
fin >> task >> x >> y;
if(task == 0)
Update(1, 1, n, pos[x], y);
else fout << solve(x, y) << "\n";
}
}