#include<bits/stdc++.h>
using namespace std;
#define N 100001
struct treeNode
{
int par; // Parent of this node
int depth; // Depth of this node
int size; // Size of subtree rooted with this node
int pos_segbase; // Position in segment tree base
int chain;
} node[N];
struct segmentTree
{
int base_array[N], tree[6*N];
} s;
vector<int> G[N];
void dfs(int curr, int prev, int dep, int n)
{
/* set parent of current node to predecessor*/
node[curr].par = prev;
node[curr].depth = dep;
node[curr].size = 1;
/* for node's every child */
vector<int>::iterator j;
for(j=G[curr].begin();j!=G[curr].end();j++)
{
if ( (*j)!=curr && (*j)!=node[curr].par )
{
/* set deeper end of the Edge as this child*/
/* do a DFS on subtree */
dfs(*j, curr, dep+1, n);
/* update subtree size */
node[curr].size+=node[*j].size;
}
}
}
int v[N];
void hld(int curr_node, int *edge_counted, int *curr_chain,
int n, int chain_heads[])
{
if (chain_heads[*curr_chain]==-1)
chain_heads[*curr_chain] = curr_node;
node[curr_node].chain = *curr_chain;
node[curr_node].pos_segbase = *edge_counted;
s.base_array[(*edge_counted)++] = v[curr_node];
int spcl_chld = -1;
vector<int>::iterator j;
for(j=G[curr_node].begin();j!=G[curr_node].end();j++)
if ( (*j)!=curr_node && (*j)!=node[curr_node].par )
if (spcl_chld==-1 || node[spcl_chld].size < node[*j].size)
spcl_chld = (*j);
if (spcl_chld!=-1)
hld(spcl_chld, edge_counted, curr_chain, n, chain_heads);
for(j=G[curr_node].begin();j!=G[curr_node].end();j++)
if ( (*j)!=curr_node && (*j)!=node[curr_node].par && (*j)!=spcl_chld)
{
(*curr_chain)++;
hld(*j, edge_counted, curr_chain, n, chain_heads);
}
}
int construct_ST(int ss, int se, int si)
{
if (ss == se-1)
{
s.tree[si] = s.base_array[ss];
return s.base_array[ss];
}
int mid = (ss + se)/2;
s.tree[si] = max(construct_ST(ss, mid, si*2),
construct_ST(mid, se, si*2+1));
return s.tree[si];
}
int update_ST(int ss, int se, int si, int x, int val)
{
if(ss > x || se <= x);
else if(ss == x && ss == se-1)s.tree[si] = val;
else
{
int mid = (ss + se)/2;
s.tree[si] = max(update_ST(ss, mid, si*2, x, val),
update_ST(mid, se, si*2+1, x, val));
}
return s.tree[si];
}
int LCA(int u, int v, int n)
{
int LCA_aux[n+5];
if (node[u].depth < node[v].depth)
swap(u, v);
memset(LCA_aux, -1, sizeof(LCA_aux));
while (u!=-1)
{
LCA_aux[u] = 1;
u = node[u].par;
}
while (v)
{
if (LCA_aux[v]==1)break;
v = node[v].par;
}
return v;
}
int RMQUtil(int ss, int se, int qs, int qe, int index)
{
if (qs <= ss && qe >= se-1)
return s.tree[index];
if (se-1 < qs || ss > qe)
return -1;
int mid = (ss + se)/2;
return max(RMQUtil(ss, mid, qs, qe, 2*index),
RMQUtil(mid, se, qs, qe, 2*index+1));
}
int RMQ(int qs, int qe, int n)
{
// Check for erroneous input values
if (qs < 0 || qe > n || qs > qe)
{
printf("Invalid Input");
return -1;
}
return RMQUtil(0, n, qs, qe, 1);
}
int crawl_tree(int u, int v, int n, int chain_heads[])
{
int chain_u, chain_v = node[v].chain, ans = 0;
while (true)
{
chain_u = node[u].chain;
if (chain_u==chain_v)
{
if (u==v); //trivial
else
ans = max(RMQ(node[v].pos_segbase+1, node[u].pos_segbase, n),
ans);
break;
}
else
{
ans = max(ans,
RMQ(node[chain_heads[chain_u]].pos_segbase,
node[u].pos_segbase, n));
u = node[chain_heads[chain_u]].par;
}
}
return ans;
}
int maxNode(int u, int v, int n, int chain_heads[])
{
int lca = LCA(u, v, n);
int ans = max(crawl_tree(u, lca, n, chain_heads),
crawl_tree(v, lca, n, chain_heads));
return ans;
}
// driver function
int main()
{
int n,m,i,a,b,t;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
fin>>n>>m;
for(i=1;i<=n;i++)
fin>>v[i];
for(i=1;i<n;i++)
{
fin>>a>>b;
G[a].push_back(b);
G[b].push_back(a);
}
int root = 1, parent_of_root=-1, depth_of_root=0;
dfs(root, parent_of_root, depth_of_root, n);
int chain_heads[N];
memset(chain_heads, -1, sizeof(chain_heads));
int edge_counted = 0;
int curr_chain = 0;
hld(root, &edge_counted, &curr_chain, n, chain_heads);
construct_ST(0, edge_counted, 1);
//cout<<s.tree[1];
for(i=1;i<=m;i++)
{
fin>>t>>a>>b;
if(!t)
update_ST(0,n,1,node[a].pos_segbase,b);
if(t==1)
fout<<maxNode(a,b,n,chain_heads)<<'\n';
}
fin.close();
fout.close();
return 0;
}