#include <bits/stdc++.h>
#define mid ((st+dr)>>1)
#define left_son (node<<1)
#define right_son ((node<<1)+1)
using namespace std;
const int Nmax = 1e5+5;
int *aint[Nmax];
int q, x, y, n, i, nr, qq;
int dad[Nmax], l[Nmax], w[Nmax], level[Nmax], to[Nmax], pos[Nmax], val[Nmax];
vector<int> edge[Nmax], sons[Nmax], chain[Nmax];
void dfs(int node)
{
w[node] = 1;
for(auto it : edge[node])
if(!level[it])
{
sons[node].push_back(it);
dad[it] = node;
level[it] = level[node]+1;
dfs(it);
w[node] += w[it];
}
}
void chains(int node)
{
to[node] = nr;
chain[nr].push_back(node);
pos[node] = chain[nr].size();
int Max=0, xson=0;
for(auto it : sons[node])
if(Max < w[it]) Max = w[it], xson=it;
if(xson) chains(xson);
for(auto it : sons[node])
if(it!=xson)
{
++nr;
chains(it);
}
}
void build(int ind, int node, int st, int dr)
{
if(st==dr)
{
aint[ind][node] = val[chain[ind][st-1]];
return;
}
build(ind, left_son, st, mid);
build(ind, right_son, mid+1, dr);
aint[ind][node] = max(aint[ind][left_son], aint[ind][right_son]);
}
void update(int ind, int node, int st, int dr, int target, int val)
{
if(st==dr)
{
aint[ind][node] = val;
return;
}
if(target<=mid) update(ind, left_son, st, mid, target, val);
else update(ind, right_son, mid+1, dr, target, val);
aint[ind][node] = max(aint[ind][left_son], aint[ind][right_son]);
}
int query(int ind, int node, int st, int dr, int Left, int Right)
{
if(Left<=st && dr<=Right)
return aint[ind][node];
int ans = 0;
if(Left<=mid) ans = max(ans, query(ind, left_son, st, mid, Left, Right));
if(mid<Right) ans = max(ans, query(ind, right_son, mid+1, dr, Left, Right));
return ans;
}
int go(int x, int y)
{
if(to[x]==to[y])
{
if(pos[x]>pos[y]) swap(x,y);
return query(to[x], 1, 1, l[to[x]], pos[x], pos[y]);
}
int dadx = chain[to[x]][0], dady = chain[to[y]][0];
if(level[dadx]<level[dady])
{
swap(x,y);
swap(dadx, dady);
}
return max( query(to[x], 1, 1, l[to[x]], 1, pos[x]), go(dad[dadx], y) );
}
int main()
{
freopen("heavypath.in", "r", stdin);
freopen("heavypath.out", "w", stdout);
scanf("%d%d", &n, &q);
for(i=1; i<=n; ++i) scanf("%d", &val[i]);
for(i=1; i<n; ++i)
{
scanf("%d%d", &x, &y);
edge[x].push_back(y);
edge[y].push_back(x);
}
level[1] = nr = 1;
dfs(1);
chains(1);
for(i=1; i<=nr; ++i)
{
l[i] = chain[i].size();
aint[i] = new int [l[i]<<2];
build(i, 1, 1, l[i]);
}
while(q--)
{
scanf("%d%d%d", &qq, &x, &y);
if(qq==0) update(to[x], 1, 1, l[to[x]], pos[x], y);
else printf("%d\n", go(x,y));
}
return 0;
}