#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5;
int n, m, v[1 + MAXN], link[1 + MAXN], sz[1 + MAXN], niv[1 + MAXN], poz[1 + MAXN], lant_tata[1 + MAXN];
vector<int>g[1 + MAXN], lant[1 + MAXN], aint[1 + MAXN];
void change(vector<int>&tree, int pos, int val, int st, int dr, int nod) {
if(pos < st || pos > dr) return;
if(st == dr) {
tree[nod] = val; return;}
int mij = (st + dr) / 2;
change(tree, pos, val, st, mij, nod * 2), change(tree, pos, val, mij + 1, dr, nod * 2 + 1);
tree[nod] = max(tree[nod * 2], tree[nod * 2 + 1]);
}
int query(vector<int>&tree, int x, int y, int st, int dr, int nod) {
if(x > dr || st > y) return 0;
if(st >= x && dr <= y) return tree[nod];
int mij = (st + dr) / 2;
return max(query(tree, x, y, st, mij, nod * 2), query(tree, x, y, mij + 1, dr, nod * 2 + 1));
}
void read() {
cin >> n >> m;
for(int i = 1; i <= n; ++i)
cin >> v[i];
for(int i = 1; i < n; ++i)
{
int x, y;
cin >> x >> y;
g[x].push_back(y), g[y].push_back(x);
}
}
void df(int nod, int tata) {
int best = 0;
niv[nod] = niv[tata] + 1;
sz[nod] = 1;
link[nod] = nod;
for(auto fiu: g[nod])
{
if(fiu == tata) continue;
df(fiu, nod);
lant_tata[link[fiu]] = nod;
sz[nod] += sz[fiu];
if(sz[fiu] > sz[best]) best = fiu, link[nod] = link[fiu];
}
lant[link[nod]].push_back(nod);
}
void build()
{
lant_tata[link[1]] = 0;
for(int i = 1; i <= n; ++i)
{
reverse(lant[i].begin(), lant[i].end());
aint[i].resize(lant[i].size() * 4 + 9);
int act = 1;
for(auto it : lant[i]) {
poz[it] = act;
change(aint[i], act, v[it], 1, lant[i].size(), 1);
act++;
}
}
}
int query(int x, int y) {
int ans = 0;
while(1) {
if(link[x] == link[y]) {
if(niv[x] < niv[y]) swap(x, y);
ans = max(ans, query(aint[link[x]], poz[y], poz[x], 1, lant[link[x]].size(), 1));
break;
}
if(niv[lant_tata[link[x]]] < niv[lant_tata[link[y]]]) swap(x, y);
ans = max(ans, query(aint[link[x]], 1, poz[x], 1, lant[link[x]].size(), 1));
x = lant_tata[link[x]];
}
return ans;
}
void solve() {
for(int step = 1, t, x, y; step <= m; ++step)
{
cin >> t >> x >> y;
int chain = link[x];
if(t == 0) v[x] = y, change(aint[chain], poz[x], y, 1, lant[chain].size(), 1);
else
cout << query(x, y) << '\n';
}
}
int main()
{
freopen("heavypath.in", "r", stdin);
freopen("heavypath.out", "w", stdout);
read();
df(1, 0);
build();
solve();
return 0;
}