#include <fstream>
#include <vector>
using namespace std;
ifstream cin("heavypath.in");
ofstream cout("heavypath.out");
const int NMAX = 1e5;
int N, M, a[NMAX + 2];
vector <int> g[NMAX + 2];
int dad[NMAX + 2], w[NMAX + 2], h[NMAX + 2];
int heavyHead[NMAX + 2];
vector <int> order;
int pos[NMAX + 2];
void dfs(int node, int dady)
{
dad[node] = dady;
w[node] = 1;
h[node] = h[dady] + 1;
for(auto it : g[node])
if(it != dady)
{
dfs(it, node);
w[node] += w[it];
}
}
void dfsHeavy(int node)
{
order.push_back(node);
pos[node] = order.size();
int heavySon = g[node][0];
if(heavySon == dad[node])
{
if(g[node].size() == 1)
return;
heavySon = g[node][1];
}
for(auto it : g[node])
if(it != dad[node] && w[it] > w[heavySon])
heavySon = it;
heavyHead[heavySon] = heavyHead[node];
dfsHeavy(heavySon);
for(auto it : g[node])
if(it != dad[node] && it != heavySon)
dfsHeavy(it);
}
struct Aint
{
int v[4 * NMAX];
void Update(int node, int st, int dr, int pos, int val)
{
if(st == dr)
{
v[node] = val;
return;
}
int mid = (st + dr) >> 1;
if(pos <= mid)
Update(2 * node, st, mid, pos, val);
else
Update(2 * node + 1, mid + 1, dr, pos, val);
v[node] = max(v[2 * node], v[2 * node + 1]);
}
int Query(int node, int st, int dr, int l, int r)
{
if(r < st || l > dr)
return 0;
if(l <= st && dr <= r)
return v[node];
int mid = (st + dr) >> 1;
return max(Query(2 * node, st, mid, l, r), Query(2 * node + 1, mid + 1, dr, l, r));
}
};
Aint aint;
int Query(int x, int y)
{
if(heavyHead[x] == heavyHead[y])
{
int st = pos[x], dr = pos[y];
if(st > dr)
swap(st, dr);
return aint.Query(1, 1, N, st, dr);
}
if(h[heavyHead[x]] > h[heavyHead[y]])
{
int ans1 = aint.Query(1, 1, N, pos[heavyHead[x]], pos[x]);
return max(ans1, Query(dad[heavyHead[x]], y));
}
int ans1 = aint.Query(1, 1, N, pos[heavyHead[y]], pos[y]);
return max(ans1, Query(dad[heavyHead[y]], x));
}
int main()
{
cin >> N >> M;
for(int i = 1; i <= N; i++)
cin >> a[i];
for(int i = 1; i < N; i++)
{
int x, y;
cin >> x >> y;
g[x].push_back(y);
g[y].push_back(x);
}
dfs(1, 0);
for(int i = 1; i <= N; i++)
heavyHead[i] = i;
dfsHeavy(1);
for(int i = 1; i <= N; i++)
aint.Update(1, 1, N, pos[i], a[i]);
for(int i = 1; i <= M; i++)
{
int t, x, y;
cin >> t >> x >> y;
if(t == 0)
aint.Update(1, 1, N, pos[x], y);
else
cout << Query(x, y) << '\n';
}
return 0;
}