// 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 STN
{
int x;
friend STN operator+(STN a, STN b)
{
return {std::max(a.x, b.x)};
}
};
struct ST
{
int N;
STN v[NMAX*2];
#define left n+1
#define right n+(mid-l+1)*2
void init(int _N, int* _v)
{
N=_N;
init(0, 0, N-1, _v);
}
void init(int n, int l, int r, int* _v)
{
if(l==r)
v[n].x=_v[l];
else
{
int mid=(l+r)/2;
init(left, l, mid, _v);
init(right, mid+1, r, _v);
v[n]=v[left]+v[right];
}
}
void update(int p, int x)
{
update(0, 0, N-1, p, x);
}
void update(int n, int l, int r, int p, int x)
{
if(l==r)
v[n].x=x;
else
{
int mid=(l+r)/2;
if(p<=mid)
update(left, l, mid, p, x);
else
update(right, mid+1, r, p, x);
v[n]=v[left]+v[right];
}
}
STN query(int l, int r)
{
return query(0, 0, N-1, l, r);
}
STN query(int n, int l, int r, int ql, int qr)
{
if(ql<=l && r<=qr)
return v[n];
int mid=(l+r)/2;
if(ql<=mid && mid<qr)
return query(left, l, mid, ql, qr)+query(right, mid+1, r, ql, qr);
if(ql<=mid)
return query(left, l, mid, ql, qr);
return query(right, mid+1, r, ql, qr);
}
#undef left
#undef right
};
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]).x);
a=tt[chain[a]];
}
if(dpt[a]<dpt[b])
std::swap(a, b);
ans=std::max(ans, S.query(poz[b], poz[a]).x);
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;
}