#include "bits/stdc++.h"
const int SIZE = 100000;
struct Node{
std :: vector < int > adj;
int val;
int depth;
int parent;
int heavy;
int head;
int in;
Node(): val(0), depth(0), parent(0), heavy(-1), head(0), in(0){}
};
int aint[4 * SIZE + 5];
Node nd[SIZE + 5];
int n, q;
//SegmentTree - START
void Update(int node, int left, int right, int idx, int val){
if(left == right){
aint[node] = val;
return;
}
int mid = (left + right) >> 1;
if(idx <= mid){
Update(2 * node, left, mid, idx, val);
}else{
Update(2 * node + 1, mid + 1, right, idx, val);
}
aint[node] = std :: max(aint[2 * node], aint[2 * node + 1]);
}
int Query(int node, int left, int right, int L, int R){
if(R < left or L > right){
return INT_MIN;
}
if(L <= left and right <= R){
return aint[node];
}
int mid = (left + right) >> 1;
int ansL = Query(2 * node, left, mid, L, R);
int ansR = Query(2 * node + 1, mid + 1, right, L, R);
return std :: max(ansL, ansR);
}
void Init(){
for(int i = 1; i <= n; i++){
Update(1, 1, n, nd[i].in, nd[i].val);
}
}
//SegmentTree - STOP
//HLD - START
int Heavy_Dfs(int node){
int my_size = 1, max_child_size = 0;
for(int i : nd[node].adj){
if(i != nd[node].parent){
nd[i].parent = node;
nd[i].depth = nd[node].depth + 1;
int child_size = Heavy_Dfs(i);
my_size += child_size;
if(child_size > max_child_size){
max_child_size = child_size;
nd[node].heavy = i;
}
}
}
return my_size;
}
void Descompose_dfs(int node, int head){
static int time = 0;
nd[node].head = head;
nd[node].in = ++time;
if(nd[node].heavy != -1){
Descompose_dfs(nd[node].heavy, head);
}
for(int i : nd[node].adj){
if(i != nd[node].parent and i != nd[node].heavy){
Descompose_dfs(i, i); // start a new path
}
}
}
int PathQuery(int a, int b){
int result = INT_MIN;
while(nd[a].head != nd[b].head){
if(nd[nd[a].head].depth > nd[nd[b].head].depth){
std :: swap(a, b);
}
result = std :: max(result, Query(1, 1, n, nd[nd[b].head].in, nd[b].in));
b = nd[nd[b].head].parent;
}
if(nd[a].depth > nd[b].depth){
std :: swap(a, b);
}
result = std :: max(result, Query(1, 1, n, nd[a].in, nd[b].in));
return result;
}
// HLD - END
void Read(){
std :: cin >> n >> q;
for(int i = 1; i <= n; i++){
std :: cin >> nd[i].val;
}
for(int i = 1; i < n; i++){
int x, y;
std :: cin >> x >> y;
nd[x].adj.push_back(y);
nd[y].adj.push_back(x);
}
}
void ProcessQueries(){
while(q -- ){
int type, x, y;
std :: cin >> type >> x >> y;
if(type == 0){
Update(1, 1, n, nd[x].in, y);
}else{
std :: cout << PathQuery(x, y) << '\n';
}
}
}
signed main(){
std :: ios_base :: sync_with_stdio(false);
std :: cin.tie(0);
freopen("heavypath.in", "r", stdin);
freopen("heavypath.out", "w", stdout);
Read();
Heavy_Dfs(1);
Descompose_dfs(1, 1);
Init();
ProcessQueries();
return 0;
}