#include <iostream>
#include <stdio.h>
#include <vector>
#include <iterator>
using namespace std;
#define NMAX 100005
#define li long int
#define MIN(x,y) (niv[x] < niv[y]) ? x : y
#define compute(x,y) (v[x] > v[y]) ? x : y
int N, M, L, i, j, k, weight[NMAX], niv[NMAX], posINlant[NMAX], nrlant[NMAX], tatal[NMAX]; /// radacina lantului
li v[NMAX];
int *stlant[NMAX];
vector<int>muchie[NMAX], lant[NMAX];
int DFS1(int xp,int h)
{
int wxp, imw, mw, w, ok, l; /// wxp weight xp, imw index max weight, mx max weight, w of sons, ok marcheaza frunza, l lant xp
wxp = imw = mw = w = ok = 0;
niv[xp] = h;
for(vector<int>::iterator it = muchie[xp].begin() ; it != muchie[xp].end() ; ++it)
if( niv[*it] == 0 )
{
ok = 1;
w = DFS1(*it,h+1);
wxp += w + 1;
tatal[nrlant[*it]] = xp; /// radacina lanturilor fiilor este xp
if( mw <= w ) /// sa stiu pe care lant al fiilor il aleg
{
imw = *it;
mw = w;
}
}
if( ok == 0 ) /// creez un lant nou in frunze
l = ++L;
else
l = nrlant[imw];
nrlant[xp] = l;
lant[l].push_back(xp);
posINlant[xp] = lant[l].size();
return wxp;
}
void ST_build()
{
for(i = 1 ; i <= N ; ++i)
posINlant[i] = lant[nrlant[i]].size() - posINlant[i] + 1; /// atribui pozitia corecta in lant de sus in jos
for(i = 1 ; i <= L ; ++i)
{
int n = lant[i].size();
stlant[i] = new int[2*n+5];
for(k = 0 ; k < 2*n ; ++k)
stlant[i][k] = 0;
for(vector<int>::iterator it = lant[i].begin() ; it != lant[i].end() ; ++it)
stlant[i][n+( posINlant[*it]-1 )] = *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_HPD(int x,int y)
{
int sol = 0;
while( true )
{
if( nrlant[x] == nrlant[y] )
{
sol = compute(sol , ST_query(posINlant[x], posINlant[y], nrlant[x], lant[nrlant[x]].size()) );
break;
}
if( niv[ tatal[nrlant[x]] ] < niv[ tatal[nrlant[y]] ] )
swap(x,y);
sol = compute(sol , ST_query(posINlant[x], 1, nrlant[x], lant[nrlant[x]].size()) );
x = tatal[nrlant[x]];
}
return sol;
}
int main()
{
li 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("%ld",&v[i+1]);
for(i = 1 ; i < N ; ++i)
{
scanf("%ld %ld", &x, &y);
muchie[x].push_back(y);
muchie[y].push_back(x);
}
rad = 1; L = 0;
DFS1(rad,1); tatal[nrlant[rad]] = 0; ST_build();
for(i = 0 ; i < M ; ++i)
{
scanf("%ld %ld %ld", &q, &x, &y);
if( q == 0 )
ST_modify(x,y);
else
printf("%ld\n", v[lant_sol_HPD(x,y)] );
}
return 0;
}