#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#define pb push_back
using namespace std;
ifstream fin( "heavypath.in" );
ofstream fout( "heavypath.out" );
const int MAXN = 100005;
int aint[4 * MAXN], n;
int init_val[MAXN], fth[MAXN], dim[MAXN], heavySon[MAXN], head[MAXN], level[MAXN];
int ind[MAXN], vertex[MAXN], sz;
bool used[MAXN];
vector<int> T[MAXN];
void predfs( int u ) {
int mx = 0;
dim[u] = 1;
used[u] = true;
for ( int v : T[u] ) {
if ( !used[v] ) {
level[v] = level[u] + 1;
predfs( v );
fth[v] = u;
dim[u] += dim[v];
if ( dim[v] > mx ) {
mx = dim[v];
heavySon[u] = v;
}
}
}
}
void dfsPaths( int u, int this_head ) {
used[u] = true;
ind[u] = sz;
head[u] = this_head;
vertex[sz++] = u;
if ( !heavySon[u] ) {
return;
}
dfsPaths( heavySon[u], this_head );
for ( int v : T[u] ) {
if ( !used[v] ) {
dfsPaths( v, v );
}
}
}
void update( int node, int l, int r, int pos, int val ) {
if ( l == r ) {
aint[node] = val;
return;
}
int mid = (l + r) / 2;
if ( pos <= mid ) {
update( 2 * node, l, mid, pos, val );
} else {
update( 2 * node + 1, mid + 1, r, pos, val );
}
aint[node] = max( aint[2 * node], aint[2 * node + 1] );
}
int query( int node, int l, int r, int x, int y ) {
int res = 0;
if ( x <= l && r <= y ) {
return aint[node];
}
int mid = (l + r) / 2;
if ( x <= mid ) {
res = max( res, query( 2 * node, l, mid, x, y ) );
}
if ( y > mid ) {
res = max( res, query( 2 * node + 1, mid + 1, r, x, y ) );
}
return res;
}
inline int realQuery( int u, int v ) {
int res = 0;
while ( head[u] != head[v] ) {
if ( level[head[u]] < level[head[v]] ) {
swap( u, v );
}
res = max( res, query( 1, 1, n, ind[head[u]], ind[u] ) );
u = fth[head[u]];
}
if ( level[u] > level[v] ) {
swap( u, v );
}
res = max( res, query( 1, 1, n, ind[u], ind[v] ) );
return res;
}
inline void realUpdate( int u, int val ) {
update( 1, 1, n, ind[u], val );
}
int main() {
int t, x, y, tp;
fin >> n >> t;
for ( int i = 1; i <= n; ++i ) {
fin >> init_val[i];
}
for ( int i = 1; i < n; ++i ) {
fin >> x >> y;
T[x].pb( y );
T[y].pb( x );
}
sz = 1;
predfs( 1 );
for ( int i = 1; i <= n; ++i ) used[i] = false;
dfsPaths( 1, 1 );
for ( int i = 1; i <= n; ++i ) {
update( 1, 1, n, ind[i], init_val[i] );
}
while ( t-- ) {
fin >> tp >> x >> y;
if ( tp == 0 ) {
realUpdate( x, y );
} else {
fout << realQuery( x, y ) << "\n";
}
}
fin.close();
fout.close();
return 0;
}