#include <stdio.h>
#include <vector>
#include <algorithm>
struct Splay {
struct Node {
int c[2], par;
int key, flip, path;
Node(): par(0), key(0), flip(false), path(0) { c[0] = c[1] = 0; }
};
std::vector<Node> t;
Splay( int n ): t(n + 1) {}
void push( int u ) {
if( !t[u].flip ) return;
std::swap( t[u].c[0], t[u].c[1] );
int left = t[u].c[0], right = t[u].c[1];
if( left ) t[left].flip ^= true;
if( right ) t[right].flip ^= true;
t[u].flip = false;
}
void pull( int u ) {
t[u].path = std::max( t[t[u].c[0]].path, std::max( t[u].key, t[t[u].c[1]].path ) );
}
int side( int x ) {
int y = t[x].par;
if( t[y].c[0] == x ) return 0;
if( t[y].c[1] == x ) return 1;
return -1;
}
void link( int u, int v, int side ) {
if( v ) t[v].par = u;
if( u && ~side ){
t[u].c[side] = v;
pull( u );
}
}
void zig( int x ) {
int y = t[x].par, sx = side( x );
int mij = t[x].c[!sx], up = t[y].par, sy = side( y );
link( y, mij, sx );
link( x, y, !sx );
link( up, x, sy );
}
void splay( int x ) {
while( ~side( x ) ){
int y = t[x].par;
if( !~side( y ) ){
push( y );
push( x );
zig( x );
return;
}
int z = t[y].par;
push( z );
push( y );
push( x );
zig( side( x ) == side( y ) ? y : x );
zig( x );
}
}
};
struct LinkCut : Splay {
LinkCut( int n ): Splay(n) {}
void expose( int u ) {
int uu = u, joe = 0;
while( u ){
splay( u );
push( u );
t[u].c[1] = joe;
pull( u );
joe = u;
u = t[u].par;
}
splay( uu );
}
void reroot( int u ) {
expose( u );
t[u].flip ^= true;
}
void Link( int a, int b ) {
expose( a );
reroot( b );
t[b].par = a;
}
int Path( int a, int b ) {
reroot( a );
expose( b );
return t[b].path;
}
void Update( int u, int val ) {
expose( u );
t[u].key = val;
pull( u );
}
};
int main() {
FILE *fin = fopen( "heavypath.in", "r" );
FILE *fout = fopen( "heavypath.out", "w" );
int n, q;
fscanf( fin, "%d%d", &n, &q );
LinkCut zile(n);
for( int i = 1; i <= n; i++ ){
int val;
fscanf( fin, "%d", &val );
zile.Update( i, val );
}
for( int i = 1; i < n; i++ ){
int a, b;
fscanf( fin, "%d%d", &a, &b );
zile.Link( a, b );
}
for( int i = 0; i < q; i++ ){
int task, x, y;
fscanf( fin, "%d %d%d", &task, &x, &y );
if( task == 0 )
zile.Update( x, y );
else
fprintf( fout, "%d\n", zile.Path( x, y ) );
}
fclose( fin );
fclose( fout );
return 0;
}