#include <bits/stdc++.h>
using namespace std;
ifstream fin( "heavypath.in" );
ofstream fout( "heavypath.out" );
const int NMAX = 1e5;
vector <int> parent;
vector <int> head;
vector <int> heavy;
vector <int> depth;
vector <int> pos;
vector <int> g[NMAX + 2];
int v[NMAX + 2];
int aint[4 * NMAX + 2];
int poscurr, n;
int dfs( int node ) {
int sz = 1;
int max_size = 0;
for( int next : g[node] ) {
if( next != parent[node] ) {
parent[next] = node;
depth[next] = 1 + depth[node];
int csz = dfs(next);
sz += csz;
if( max_size < csz ) {
max_size = csz;
heavy[node] = next;
}
}
}
return sz;
}
void decompuse( int node, int sef ){
head[node] = sef;
pos[node] = ++poscurr;
if( heavy[node] != -1 )
decompuse(heavy[node], sef);
for( int next : g[node] ) {
if( next != parent[node] && heavy[node] != next )
decompuse(next, next);
}
}
void init() {
parent = vector <int> (1 + n);
head = vector <int> (1 + n);
heavy = vector <int> (1 + n, -1);
depth = vector <int> (1 + n);
pos = vector <int> (1 + n);
dfs(1);
decompuse(1, 1);
}
void update( int node, int from, int to, int pos, int x ) {
if( from == to ) {
aint[node] = x;
return ;
}
int mid = (from + to) >> 1;
if( pos <= mid )
update(2 * node, from, mid, pos, x);
else
update(2 * node + 1, mid + 1, to, pos, x);
aint[node] = max(aint[2 * node], aint[2 * node + 1]);
}
int query( int node, int from, int to, int x, int y ) {
if( from == x && y == to )
return aint[node];
int mid = (from + to) >> 1;
if( y <= mid )
return query(2 * node, from, mid, x, y);
else if( x > mid )
return query(2 * node + 1, mid + 1, to, x, y);
return max(query(2 * node, from, mid, x, mid), query(2 * node + 1, mid + 1, to, mid + 1, y));
}
int plm( int a, int b ){
return query(1, 1, n, min(a, b), max(a, b));
}
int solve( int a, int b ) {
int ans = 0;
for( ; head[a] != head[b]; b = parent[head[b]] ) {
if( depth[head[a]] > depth[head[b]] )
swap(a, b);
ans = max(ans, plm(pos[head[b]], pos[b]));
}
if( depth[a] > depth[b] )
swap(a, b);
ans = max(ans, plm(pos[a], pos[b]));
return ans;
}
int main() {
int m, i, c, a, b;
fin >> n >> m;
for( i = 1; i <= n; ++i )
fin >> v[i];
for( i = 0; i < n - 1; ++i ) {
fin >> a >> b;
g[a].push_back(b);
g[b].push_back(a);
}
init();
for( i = 1; i <= n; ++i )
update(1, 1, n, pos[i], v[i]);
while( m-- ) {
fin >> c >> a >> b;
if( c == 0 )
update(1, 1, n, pos[a], b);
else
fout << plm(a, b) << "\n";
}
return 0;
}