#include <fstream>
#include <vector>
#include <cmath>
#include <algorithm>
#define MAX(a, b) (((a)>(b))?(a):(b))
const int N = 1e5 + 5;
std::vector<int>l[N], hl[N];
int bigboss[N], k, v[N], col[N];
int mx[N], n, m, tata[N], poz[N];
int euler[2*N], e, f_app[N];
int rmq[25][N], h[N];
int aint[8*N], sz, cnt;
std::ifstream fin("heavypath.in");
std::ofstream fout("heavypath.out");
void dfs(int node = 1, int from = 0) {
euler[++e] = node;
f_app[node] = e;
tata[node] = from;
h[node] = h[from] + 1;
rmq[0][e] = node;
if(l[node].size()==1 and l[node][0]==from) {
bigboss[++k] = node;
hl[k].push_back(node);
mx[node] = 1;
col[node] = k;
return;
}
int c, mmax=0;
for(int to:l[node]) if(from!=to) {
dfs(to, node);
euler[++e] = node;
rmq[0][e] = node;
if(mx[to]>mmax) mmax = mx[to], c = to;
}
bigboss[col[c]]=node;
hl[col[c]].push_back(node);
mx[node] = mmax;
col[node] = col[c];
for(int to:l[node]) if(from!=to)
if(mx[to]+1>mx[node]) mx[node] = mx[to] + 1;
}
int Min(int a, int b) {
return ((h[a]>h[b])?b:a);
}
int Lca(int from, int to) {
if(f_app[from]>f_app[to]) std::swap(from, to);
int lg = (int)log2(f_app[to]-f_app[from]+1);
return Min(rmq[lg][f_app[from]], rmq[lg][f_app[to]-(1<<lg)+1]);
}
void update(int node, int st, int dr, int x, int y) {
if(st>dr or x<st or x>dr) return;
if(st==dr) {
aint[node]=y;
return;
}
int mij = (st+dr)>>1;
update(2*node, st, mij, x, y);
update(2*node+1, mij+1, dr, x, y);
aint[node] = MAX(aint[2*node], aint[2*node+1]);
}
int query(int node, int st, int dr, int x, int y) {
if(x<=st and dr<=y) return aint[node];
if(y<st or dr<x) return 0;
int mij = (st+dr)>>1;
return MAX(query(2*node, st, mij, x, y), query(2*node+1, mij+1, dr, x, y));
}
void solve(int from, int to) {
int lca = Lca(from, to), ans = 0;
while(col[from]!=col[lca]) {
ans = MAX(ans, query(1, 1, sz, poz[bigboss[col[from]]], poz[from]));
from = tata[bigboss[col[from]]];
}
ans = MAX(ans, query(1, 1, sz, poz[lca], poz[from]));
while(col[to]!=col[lca]) {
ans = MAX(ans, query(1, 1, sz, poz[bigboss[col[to]]], poz[to]));
to = tata[bigboss[col[to]]];
}
ans = MAX(ans, query(1, 1, sz, poz[lca], poz[to]));
fout<<ans<<"\n";
}
int main() {
fin>>n>>m;
for(int i=1;i<=n;i++) fin>>v[i];
for(int i=1;i<n;i++) {
int from, to;
fin>>from>>to;
l[from].push_back(to);
l[to].push_back(from);
}
dfs();
for(int j=1;(1<<j)<=e;j++)
for(int i=1;i+(1<<j)-1<=e;i++)
rmq[j][i] = Min(rmq[j-1][i], rmq[j-1][i+(1<<(j-1))]);
for(int i=1;i<=k;i++) sz+=hl[i].size(), std::reverse(hl[i].begin(), hl[i].end());
for(int i=1;i<=k;i++)
for(int to:hl[i])
update(1, 1, sz, ++cnt, v[to]), poz[to] = cnt;
while(m--) {
int op, x, y;
fin>>op>>x>>y;
if(!op) update(1, 1, sz, poz[x], y);
else solve(x, y);
}
}