#include <bits/stdc++.h>
using namespace std;
const int NMAX = 100005;
int N, M, v[NMAX];
int aint[4 * NMAX];
int height[NMAX];
vector <int> paths[NMAX];
vector <int> graph[NMAX];
int cntPaths;
int pathInd[NMAX];
int pathFather[NMAX];
int pathGap[NMAX];
int weight[NMAX];
int answer;
void dfs(int node, int father)
{
height[node] = height[father] + 1;
weight[node] = 1;
int heaviestSon = -1;
for (auto& son : graph[node])
{
if (son != father)
{
dfs(son, node);
weight[node] += weight[son];
if (heaviestSon == -1 || weight[heaviestSon] < weight[son])
heaviestSon = son;
}
}
if (graph[node].size() == 1 && node != 1)
{
++cntPaths;
pathInd[node] = cntPaths;
paths[cntPaths].push_back(node);
return;
}
pathInd[node] = pathInd[heaviestSon];
paths[pathInd[node]].push_back(node);
for (auto& son : graph[node])
if (son != father && son != heaviestSon)
pathFather[pathInd[son]] = node;
}
int LeftSon(int node)
{
return 2 * node;
}
int RightSon(int node)
{
return 2 * node + 1;
}
void Build(int node, int left, int right, int gap, int path)
{
if (left == right)
{
aint[node + gap] = v[paths[path][left - 1]];
return;
}
int mid = (left + right) / 2;
Build(LeftSon(node), left, mid, gap, path);
Build(RightSon(node), mid + 1, right, gap, path);
aint[node + gap] = max(aint[LeftSon(node) + gap], aint[RightSon(node) + gap]);
}
void HeavyLightDecomposition()
{
dfs(1, 0);
for (int i = 1;i <= cntPaths;++i)
{
reverse(paths[i].begin(), paths[i].end());
if (i > 1)
pathGap[i] = pathGap[i - 1] + 4 * paths[i - 1].size();
Build(1, 1, paths[i].size(), pathGap[i], i);
}
}
void Update(int node, int left, int right, int pos, int val, int gap)
{
if (left == right)
{
aint[node + gap] = val;
return;
}
int mid = (left + right) / 2;
if (pos <= mid)
Update(LeftSon(node), left, mid, pos, val, gap);
else
Update(RightSon(node), mid + 1, right, pos, val, gap);
aint[node + gap] = max(aint[LeftSon(node) + gap], aint[RightSon(node) + gap]);
}
void Query(int node, int left, int right, int LeftQuery, int RightQuery, int gap)
{
if (LeftQuery <= left && right <= RightQuery)
{
answer = max(answer, aint[node + gap]);
return;
}
int mid = (left + right) / 2;
if (LeftQuery <= mid)
Query(LeftSon(node), left, mid, LeftQuery, RightQuery, gap);
if (RightQuery >= mid + 1)
Query(RightSon(node), mid + 1, right, LeftQuery, RightQuery, gap);
}
int main()
{
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
fin >> N >> M;
for (int i = 1;i <= N;++i)
fin >> v[i];
for (int i = 1;i < N;++i)
{
int u, v;
fin >> u >> v;
graph[u].push_back(v);
graph[v].push_back(u);
}
HeavyLightDecomposition();
while (M-- > 0)
{
int t, x, y;
fin >> t >> x >> y;
if (t == 0)
{
v[x] = y;
Update(1, 1, paths[pathInd[x]].size(), height[x] - height[pathFather[pathInd[x]]], y, pathGap[pathInd[x]]);
}
else
{
answer = 0;
while (true)
{
if (pathInd[x] == pathInd[y])
{
if (height[x] > height[y])
swap(x, y);
Query(1, 1, paths[pathInd[x]].size(), height[x] - height[pathFather[pathInd[x]]], height[y] - height[pathFather[pathInd[y]]], pathGap[pathInd[x]]);
break;
}
if (height[pathFather[pathInd[x]]] < height[pathFather[pathInd[y]]])
swap(x, y);
Query(1, 1, paths[pathInd[x]].size(), 1, height[x] - height[pathFather[pathInd[x]]], pathGap[pathInd[x]]);
x = pathFather[pathInd[x]];
}
fout << answer << "\n";
}
}
fin.close();
fout.close();
return 0;
}