#include <iostream>
#include <stdio.h>
#include <vector>
#include <iterator>
using namespace std;
#define NMAX 100005
#define logNMAX 20
#define MIN(x,y) (niv[x] < niv[y]) ? x : y
#define compute(x,y) (v[x] > v[y]) ? x : y
int N, M, K, L, i, j, k, v[NMAX], weight[NMAX], niv[NMAX], pos[NMAX], lg[2*NMAX], ET[logNMAX][2*NMAX], posINlant[NMAX], nrlant[NMAX], tatal[NMAX];
int *stlant[NMAX];
bool viz[NMAX];
vector<int>muchie[NMAX], lant[NMAX];
int DFS(int xp,int h)
{
int w = 0;
ET[0][++K] = xp;
pos[xp] = K;
niv[xp] = h;
for(vector<int>::iterator it = muchie[xp].begin() ; it != muchie[xp].end() ; ++it)
if( niv[*it] == 0 )
{
w += DFS(*it,h+1) + 1;
ET[0][++K] = xp;
}
weight[xp] = w;
return w;
}
void RMQ_build()
{
lg[1] = 0;
for(i = 2 ; i <= K ; ++i)
lg[i] = lg[i/2] + 1;
for(i = 1 ; i <= lg[K] ; ++i)
for(j = 1 ; j <= K ; ++j)
ET[i][j] = MIN( ET[i-1][j] , ET[i-1][j+(1<<(i-1))] );
}
int lca(int x, int y)
{
int p1,p2,l;
p1 = min(pos[x], pos[y]);
p2 = max(pos[x], pos[y]);
l = lg[p2-p1+1];
return MIN( ET[l][p1] , ET[l][p2-(1<<l)+1] );
}
void DFS_lanturi(int xp,int l)
{
int wMaxSon = 0;
viz[xp] = true;
nrlant[xp] = l;
lant[l].push_back(xp);
posINlant[xp] = lant[l].size();
for(vector<int>::iterator it = muchie[xp].begin() ; it != muchie[xp].end() ; ++it)
if( viz[*it] == false )
wMaxSon = (weight[wMaxSon] > weight[*it]) ? wMaxSon : *it;
for(vector<int>::iterator it = muchie[xp].begin() ; it != muchie[xp].end() ; ++it)
if( viz[*it] == false )
{if( *it == wMaxSon )
DFS_lanturi(*it,l);
else
{DFS_lanturi(*it,++L);
tatal[L] = xp; }
}
}
void ST_build()
{
for(i = 1 ; i <= L ; ++i)
{
int n = lant[i].size();
stlant[i] = new int[2*n];
for(k = 0 ; k < 2*n ; ++k)
stlant[i][k] = 0;
j = 0;
for(vector<int>::iterator it = lant[i].begin() ; it != lant[i].end() ; ++it)
stlant[i][n+(j++)] = *it;
for(k = n-1 ; k > 0 ; --k)
stlant[i][k] = compute(stlant[i][k*2] , stlant[i][k*2+1]);
}
}
void ST_modify(int xp,int val)
{
int n,l,p;
v[xp] = val;
l = nrlant[xp];
n = lant[l].size();
p = posINlant[xp];
for(p += n-1 ; p > 0 ; p >>= 1)
stlant[l][p>>1] = compute(stlant[l][p] , stlant[l][p^1]);
}
int ST_query(int p1, int p2, int l , int n)
{
int left, right, sol = 0; v[sol] = 0;
left = min(p1 , p2);
right= max(p1 , p2);
for(left += n-1, right += n-1 ; left <= right ; left >>= 1 , right >>= 1)
{
if( left % 2 == 1 ) { sol = compute(sol, stlant[l][left]); left++; }
if(right % 2 == 0 ) { sol = compute(sol, stlant[l][right]); right--; }
}
return sol;
}
int lant_sol(int x,int lcaxy)
{
int sol = 0;
while( true )
{
if( nrlant[x] == nrlant[lcaxy] )
{
sol = compute(sol , ST_query(posINlant[x], posINlant[lcaxy], nrlant[x], lant[nrlant[x]].size()) );
break;
}
else
{
sol = compute(sol , ST_query(posINlant[x], 1, nrlant[x], lant[nrlant[x]].size()) );
x = tatal[nrlant[x]];
}
}
return sol;
}
int ValMaxHPD(int x, int y)
{
int lcaxy = lca(x,y);
return v[ compute(lant_sol(x,lcaxy) , lant_sol(y,lcaxy)) ];
}
int main()
{
int q, x, y, rad;
freopen("heavypath.in","r",stdin);
freopen("heavypath.out","w",stdout);
scanf("%d %d", &N, &M);
for(i = 0 ; i < N ; ++i)
scanf("%d",&v[i+1]);
for(i = 1 ; i < N ; ++i)
{
scanf("%d %d", &x, &y);
muchie[x].push_back(y);
muchie[y].push_back(x);
}
rad = 1;
K = 0; L = 1; tatal[1] = rad;
DFS(rad,1); RMQ_build(); DFS_lanturi(1,L); ST_build();
for(i = 0 ; i < M ; ++i)
{
scanf("%d %d %d", &q, &x, &y);
if( q == 0 )
ST_modify(x,y);
else
printf("%d\n", ValMaxHPD(x,y));
}
return 0;
}