#include <bits/stdc++.h>
using namespace std;
const int NMAX = 1e5;
ifstream fin( "heavypath.in" );
ofstream fout( "heavypath.out" );
int val[NMAX+1];
vector <int> edges[NMAX+1];
int sz[NMAX+1];
int heavyChild[NMAX+1];
int parent[NMAX+1], depth[NMAX+1];
int n;
int aint[2*NMAX+1];
void update( int node, int left, int right, int poz, int val ) {
int mid, leftSon, rightSon;
if( left == right ) {
aint[node] = val;
return;
}
mid = ( left + right ) / 2;
leftSon = node + 1;
rightSon = node + 2 * ( mid - left + 1 );
if( poz <= mid )
update( leftSon, left, mid, poz, val );
else
update( rightSon, mid + 1, right, poz, val );
aint[node] = max( aint[leftSon], aint[rightSon] );
}
int query( int node, int left, int right, int qleft, int qright ) {
int mid, leftSon, rightSon;
if( left >= qleft && right <= qright ) {
return aint[node];
}
if( right < qleft || left > qright ) {
return 0;
}
mid = ( left + right ) / 2;
leftSon = node + 1;
rightSon = node + 2 * ( mid - left + 1 );
int ans = 0;
if( qleft <= mid )
ans = max( ans, query( leftSon, left, mid, qleft, qright ) );
if( qright >= mid + 1 )
ans = max( ans, query( rightSon, mid + 1, right, qleft, qright ) );
return ans;
}
void dfs( int node, int par, int lvl ) {
sz[node] = 1;
parent[node] = par;
depth[node] = lvl;
int maxi = -1;
for( auto vec: edges[node] ) {
if( vec != par ) {
dfs( vec, node, lvl + 1 );
sz[node] += sz[vec];
if( sz[vec] > maxi ) {
maxi = sz[vec];
heavyChild[node] = vec;
}
}
}
}
int label[NMAX+1];
int head[NMAX+1];
int t = 0;
void dfs_labels( int node, int chainHead ) {
label[node] = t++;
head[node] = chainHead;
if( heavyChild[node] != -1 ) {
dfs_labels( heavyChild[node], chainHead );
}
for( auto vec: edges[node] ) {
if( vec != parent[node] && vec != heavyChild[node] )
dfs_labels( vec, vec );
}
}
int heavy_query( int a, int b ) {
int ans = 0;
while( head[a] != head[b] ) {
if( depth[head[a]] < depth[head[b]] )
swap( a, b );
ans = max( ans, query( 0, 0, n - 1, label[head[a]], label[a] ) );
a = parent[head[a]];
}
ans = max( ans, query( 0, 0, n - 1, min( label[a], label[b] ), max( label[a], label[b] ) ) );
return ans;
}
int main() {
int q, i, a, b, op, x, y;
fin >> n >> q;
for( i = 0; i < n; i++ ) {
fin >> val[i];
heavyChild[i] = -1;
}
for( i = 0; i < n - 1; i++ ) {
fin >> a >> b;
a--, b--;
edges[a].push_back( b );
edges[b].push_back( a );
}
dfs( 0, -1, 0 );
dfs_labels( 0, 0 );
for( i = 0; i < n; i++ )
update( 0, 0, n - 1, label[i], val[i] );
for( i = 0; i < q; i++ ) {
fin >> op >> x >> y;
x--, y--;
if( op == 0 )
update( 0, 0, n - 1, label[x], y );
else {
fout << heavy_query( x, y ) << "\n";
}
}
return 0;
}