#include<fstream>
#include<vector>
#include<cstdio>
#define DIM 100005
#define DIM1 1000000
using namespace std;
int n, m, nr, i, j, x, y, sol, ii, jj, ti, maxim, r;
int aint[4 * DIM], val[DIM], t[DIM], viz[DIM], ad[DIM], ln[DIM], ind[DIM], num[DIM], tl[DIM], niv[DIM];
vector<int> v[DIM], lant[DIM];
char sir[DIM1 + 5];
FILE * fin = fopen("heavypath.in", "r");
FILE * fout = fopen("heavypath.out", "w");
int numm(){
while(sir[r] < '0' || sir[r] > '9'){
r++;
if(r == DIM1){
r = 0;
fread(sir, 1, DIM1, fin);
}
}
int x = 0;
while(sir[r] >= '0' && sir[r] <= '9'){
x = x * 10 + sir[r] - '0';
r++;
if(r == DIM1){
r = 0;
fread(sir, 1, DIM1, fin);
}
}
return x;
}
void dfs(int nod){
viz[nod] = 1;
int ii = 0;
for(int i = 0; i < v[nod].size(); i++){
int vecin = v[nod][i];
if(viz[vecin] == 0){
dfs(vecin);
if(num[ ln[vecin] ] > num[ii]){
ii = ln[vecin];
}
}
else{
t[nod] = vecin;
niv[nod] = niv[vecin] + 1;
}
}
if(ii == 0){
nr++;
num[nr] = 1;
ln[nod] = nr;
lant[nr].push_back(nod);
tl[nr] = t[nod];
}
else{
num[ii]++;
ln[nod] = ii;
tl[ii] = t[nod];
lant[ii].push_back(nod);
}
}
void build(int nod, int st, int dr, int t){
if(st == dr){
aint[nod + ad[t] ] = val[ lant[t][st - 1] ];
}
else{
int mid = (st + dr) / 2;
build(2 * nod, st, mid, t);
build(2 * nod + 1, mid + 1, dr, t);
aint[nod + ad[t] ] = max(aint[2 * nod + ad[t] ], aint[2 * nod + 1 + ad[t] ]);
}
}
void update(int nod, int st, int dr, int poz, int val, int add){
if(st == dr){
aint[nod + add] = val;
}
else{
int mid = (st + dr) / 2;
if(poz <= mid){
update(2 * nod, st, mid, poz, val, add);
}
else{
update(2 * nod + 1, mid + 1, dr, poz, val, add);
}
aint[nod + add] = max(aint[2 * nod + add], aint[2 * nod + 1 + add]);
}
}
void query(int nod, int st, int dr, int p, int u, int add){
if(p <= st && dr <= u){
maxim = max(maxim, aint[nod + add]);
}
else{
int mid = (st + dr) / 2;
if(p <= mid){
query(2 * nod, st, mid, p, u, add);
}
if(u > mid){
query(2 * nod + 1, mid + 1, dr, p, u, add);
}
}
}
int main(){
fread(sir, 1, DIM1, fin);
n = numm();
m = numm();
for(i = 1; i <= n; i++){
val[i] = numm();
}
for(i = 1; i < n; i++){
x = numm();
y = numm();
v[x].push_back(y);
v[y].push_back(x);
}
dfs(1);
for(i = 1; i <= nr; i++){
for(ii = 0, jj = lant[i].size() - 1; ii < jj; ii++, jj--){
swap(lant[i][ii], lant[i][jj]);
ind[ lant[i][ii] ] = ii;
ind[ lant[i][jj] ] = jj;
}
if(ii == jj){
ind[ lant[i][ii] ] = ii;
}
ad[i] = ad[i - 1] + 4 * lant[i - 1].size();
}
for(i = 1; i <= nr; i++){
build(1, 1, lant[i].size(), i);
}
for(; m; m--){
ti = numm();
x = numm();
y = numm();
if(ti == 1){
sol = 0;
while(ln[x] != ln[y]){
ii = ln[x];
jj = ln[y];
maxim = 0;
if(niv[ tl[ii] ] > niv[ tl[jj] ] || y == 0){
query(1, 1, lant[ii].size(), 1, ind[x] + 1, ad[ii]);
sol = max(sol, maxim);
x = tl[ii];
}
else{
query(1, 1, lant[jj].size(), 1, ind[y] + 1, ad[jj]);
sol = max(sol, maxim);
y = tl[jj];
}
}
maxim = 0;
if(x != 0){
ii = ind[x];
jj = ind[y];
x = ln[x];
if(jj < ii){
swap(ii, jj);
}
query(1, 1, lant[x].size(), ii + 1, jj + 1, ad[x]);
sol = max(sol, maxim);
}
fprintf(fout, "%d\n", sol);
}
else{
ii = ln[x];
update(1, 1, lant[ii].size(), ind[x] + 1, y, ad[ii]);
}
}
return 0;
}