#include <fstream>
#include <vector>
#define ll long long
using namespace std;
const int NMAX = 1e5;
vector <int> g[NMAX + 1];
int s[NMAX + 1];
int head[NMAX + 1];
int pos[NMAX + 1];
int comp[NMAX + 1];
int sus[NMAX + 1];
int d[NMAX + 1];
void dfs_sub(int nod, int parent)
{
d[nod] = d[parent] + 1;
sus[nod] = parent;
s[nod] = 1;
for (int x : g[nod])
if (x != parent)
{
dfs_sub(x, nod);
s[nod] += s[x];
}
}
int nr;
void dfs_heavy(int nod, int parent, int label)
{
static int time = 0;
pos[nod] = ++time;
comp[nod] = label;
for (int x : g[nod])
if (x != parent)
{
if (s[x] > s[nod] / 2)
dfs_heavy(x, nod, label);
}
for (int x : g[nod])
if (x != parent)
{
if (s[x] <= s[nod] / 2)
{
nr++;
head[nr] = x;
dfs_heavy(x, nod, nr);
}
}
}
int v[NMAX + 1];
int aint[4 * NMAX + 1];
void update(int node, int st, int dr, int poz, int val)
{
if (dr < poz or st > poz)
return ;
if (st == dr)
{
aint[node] = val;
return ;
}
int med = ((st + dr) >> 1);
update(node << 1, st, med, poz, val);
update(node << 1 | 1, med + 1, dr, poz, val);
aint[node] = max(aint[node << 1], aint[node << 1 | 1]);
}
int query(int node, int st, int dr, int a, int b)
{
if (dr < a or st > b)
return 0;
if (a <= st and dr <= b)
return aint[node];
int med = ((st + dr) >> 1);
int v1 = query(node << 1, st, med, a, b);
int v2 = query(node << 1 | 1, med + 1, dr, a, b);
return max(v1, v2);
}
int n;
int solve(int a, int b)
{
int ans = 0;
while (comp[a] != comp[b])
{
if (d[head[comp[a]]] < d[head[comp[b]]])
swap(a, b);
ans = max(ans, query(1, 1, n, pos[head[comp[a]]], pos[a]));
a = sus[head[comp[a]]];
}
if (pos[a] > pos[b])
swap(a, b);
ans = max(ans, query(1, 1, n, pos[a], pos[b]));
return ans;
}
signed main()
{
ifstream cin("heavypath.in");
ofstream cout("heavypath.out");
int i, q;
cin >> n >> q;
for (i = 1; i <= n; i++)
cin >> v[i];
for (i = 2; i <= n; i++)
{
int a, b;
cin >> a >> b;
g[a].push_back(b);
g[b].push_back(a);
}
dfs_sub(1, 0);
nr = 1;
head[1] = 1;
dfs_heavy(1, 0, 1);
for (i = 1; i <= n; i++)
update(1, 1, n, pos[i], v[i]);
while (q--)
{
int op, a, b;
cin >> op >> a >> b;
if (op == 0)
{
update(1, 1, n, pos[a], b);
}
else
cout << solve(a, b) << "\n";
}
return 0;
}