// Ilie "The-Winner" Dumitru
// Dumnezeu sa o ierte
#include<bits/stdc++.h>
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define err(...) fprintf(stderr, __VA_ARGS__)
using ll=long long;
using dbl=long double;
constexpr int NMAX=100'005;
constexpr ll MOD=1'000'000'007;
struct ST
{
int N;
int v[NMAX*2];
void init(int _N, int* _v)
{
int i;
N=_N;
for(i=0;i<N;++i)
v[i+N]=_v[i];
for(i=N-1;i>0;--i)
v[i]=std::max(v[i*2], v[i*2+1]);
}
void update(int p, int x)
{
for(v[p+=N]=x;p>0;p/=2)
v[p/2]=std::max(v[p], v[p^1]);
}
int query(int l, int r)
{
int x=0;
l+=N;
r+=N+1;
while(l<r)
{
if(l%2)
x=std::max(x, v[l++]);
if(r%2)
x=std::max(x, v[--r]);
l/=2;
r/=2;
}
return x;
}
};
int N;
int v[NMAX];
int tt[NMAX], dpt[NMAX], chain[NMAX];
std::vector<int> G[NMAX];
int sz[NMAX], poz[NMAX], cpoz;
ST S;
void dfs0(int n, int t=0)
{
int i, max=0;
dpt[n]=dpt[t]+1;
tt[n]=t;
sz[n]=1;
for(i=0;i<sz(G[n]);++i)
{
if(G[n][i]==t)
{
G[n][i]=G[n].back();
G[n].pop_back();
--i;
}
else
{
dfs0(G[n][i], n);
sz[n]+=sz[G[n][i]];
if(sz[G[n][i]]>sz[G[n][max]])
max=i;
}
}
if(max)
std::swap(G[n][0], G[n][max]);
}
void dfs1(int n)
{
poz[n]=cpoz++;
if(G[n].empty())
return;
chain[G[n][0]]=chain[n];
dfs1(G[n][0]);
for(int i=1;i<sz(G[n]);++i)
{
chain[G[n][i]]=G[n][i];
dfs1(G[n][i]);
}
}
int query(int a, int b)
{
int ans=0;
while(chain[a]!=chain[b])
{
if(dpt[a]<dpt[b])
std::swap(a, b);
ans=std::max(ans, S.query(poz[chain[a]], poz[a]));
a=tt[chain[a]];
}
if(dpt[a]<dpt[b])
std::swap(a, b);
ans=std::max(ans, S.query(poz[b], poz[a]));
return ans;
}
int main()
{
FILE* f=fopen("heavypath.in", "r"), *g=fopen("heavypath.out", "w");
int i, a, b, c, Q;
fscanf(f, "%d%d", &N, &Q);
for(i=0;i<N;++i)
fscanf(f, "%d", v+i);
for(i=1;i<N;++i)
{
fscanf(f, "%d%d", &a, &b);
--a;
--b;
G[a].push_back(b);
G[b].push_back(a);
}
dfs0(0);
dfs1(0);
for(i=0;i<N;++i)
sz[poz[i]]=v[i];
S.init(N, sz);
do
{
fscanf(f, "%d%d%d", &a, &b, &c);
if(a==0)
S.update(poz[b-1], c);
else
fprintf(g, "%d\n", query(b-1, c-1));
}while(--Q);
fclose(f);
fclose(g);
return 0;
}