# include <bits/stdc++.h>
using namespace std;
ifstream fi("heavypath.in");
ofstream fo("heavypath.out");
const int N = 1000005;
int *s[N];
vector < int > v[N];
int dp[17][N];
int h[N];
int to[N];
int ind[N];
int sum[N];
int val[N];
int p[N];
int mar[N];
void dfs(int prec,int node)
{
dp[0][node] = prec;
h[node] = h[prec] + 1;
sum[node] = 1;
for (auto it : v[node])
if (it != prec)
dfs(node,it),sum[node] += sum[it];
}
int sh(int x,int y)
{
for (int i = 16;i+1;--i)
if (y>>i&1) x = dp[i][x];
return x;
}
int lca(int x,int y)
{
if (h[x] > h[y])
x = sh(x,h[x] - h[y]);
else y = sh(y,h[y] - h[x]);
for (int i = 16;i+1 && x != y;--i)
if (dp[i][x] != dp[i][y])
x = dp[i][x],y = dp[i][y];
if (x == y) return x;
return dp[0][x];
}
void upd(int id,int p,int u,int pos,int val,int node)
{
if (p == u) s[id][node] = val;
else
{
int m = (p+u)/2;
if (pos <= m) upd(id,p,m,pos,val,node<<1);
else upd(id,m+1,u,pos,val,node<<1|1);
s[id][node] = max(s[id][node<<1],s[id][node<<1|1]);
}
}
int qry(int id,int p,int u,int l,int r,int node)
{
if (l <= p && u <= r) return s[id][node];
int mx = 0;
int m = (p+u)/2;
if (l <= m) mx = max(mx,qry(id,p,m,l,r,node<<1));
if (m+1<=r) mx = max(mx,qry(id,m+1,u,l,r,node<<1|1));
return mx;
}
int qu(int x,int y)
{
if (to[x] == to[y])
return qry(to[x],1,mar[to[x]],ind[x],ind[y],1);
else
return max(qry(to[y],1,mar[to[y]],1,ind[y],1),qu(x,p[y]));
}
int query(int x,int y)
{
int lc = lca(x,y);
return max(qu(lc,x),qu(lc,y));
}
void update(int x,int y)
{
upd(to[x],1,mar[to[x]],ind[x],y,1);
}
int arb = 0;
void DFS(int prec,int node,int len,int pl)
{
p[node] = pl;
if (sum[node] == 1)
{
s[++arb] = new int[2*len+5];
mar[arb] = len;
ind[node] = len;
to[node] = arb;
}
else
{
int mx = 0,where = 0;
for (auto it : v[node])
if (it != prec)
mx = max(mx,sum[it]);
for (auto it : v[node])
if (it != prec)
where = it;
DFS(node,where,len+1,pl);
to[node] = to[where];
ind[node] = len;
for (auto it : v[node])
if (it != prec && it != where)
DFS(node,it,1,node);
}
}
int main(void)
{
int n,m;
fi>>n>>m;
for (int i = 1;i <= n;++i) fi>>val[i];
for (int i = 1;i < n;++i)
{
int a,b;
fi>>a>>b;
v[a].push_back(b);
v[b].push_back(a);
}
dfs(0,1);
for (int i = 1;i < 17;++i)
for (int j = 1;j <= n;++j)
dp[i][j] = dp[i-1][dp[i-1][j]];
DFS(0,1,1,0);
for (int i = 1;i <= n;++i) update(i,val[i]);
while (m --)
{
int a,b,c;
fi>>a>>b>>c;
if (!a) update(b,c);
else fo << query(b,c) << '\n';
}
return 0;
}