#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
const int NMax = 1e5;
int N, M, K, Val[NMax + 5], W[NMax + 5], Ci[NMax + 5], Cj[NMax + 5], L[NMax + 5], Lev[NMax + 5], A[20][NMax + 5], TT[NMax + 5];
vector <int> G[NMax + 5], AIT[NMax + 5];
void DFS(int Nod, int Tata)
{
W[Nod] = 1, Lev[Nod] = Lev[Tata] + 1, A[0][Nod] = Tata;
for(auto Vecin : G[Nod])
if(Vecin != Tata)
DFS(Vecin, Nod), W[Nod] += W[Vecin];
}
void MakePath(int Nod, int Tata, int c)
{
Ci[Nod] = c, Cj[Nod] = ++L[c];
int maxi = -1, x = 0;
for(auto Vecin : G[Nod])
{
if(Vecin != Tata && W[Vecin] > maxi)
maxi = W[Vecin], x = Vecin;
}
if(x) MakePath(x, Nod, c);
for(auto Vecin : G[Nod])
if(Vecin != Tata && Vecin != x)
{
TT[++K] = Nod;
MakePath(Vecin, Nod, K);
}
}
int Stramos(int Nod, int P)
{
int k = 0;
while(P)
{
if(P & 1) Nod = A[k][Nod];
P >>= 1, k++;
}
return Nod;
}
int LCA(int x, int y)
{
if(Lev[x] < Lev[y]) swap(x, y);
x = Stramos(x, Lev[x] - Lev[y]);
if(x == y) return x;
for(int i = log2(Lev[x]); i >= 0; i--)
{
if(A[i][x] != A[i][y])
x = A[i][x], y = A[i][y];
}
return A[0][x];
}
void Update(int d, int i, int st, int dr, int p, int val)
{
if(p < st || dr < p) return;
if(st == dr)
{
AIT[d][i] = val;
return;
}
int m = (st + dr) / 2;
Update(d, 2 * i, st, m, p, val);
Update(d, 2 * i + 1, m + 1, dr, p, val);
AIT[d][i] = max(AIT[d][2 * i], AIT[d][2 * i + 1]);
}
int Querry(int d, int i, int st, int dr, int a, int b)
{
if(b < st || dr < a) return 0;
if(a <= st && dr <= b)
return AIT[d][i];
int m = (st + dr) >> 1;
return max(Querry(d, 2 * i, st, m, a, b), Querry(d, 2 * i + 1, m + 1, dr, a, b));
}
int Solve(int x, int y)
{
int Sol = 0;
while(Ci[x] != Ci[y])
{
Sol = max(Sol, Querry(Ci[x], 1, 1, L[Ci[x]], 1, Cj[x]));
x = TT[Ci[x]];
}
return max(Sol, Querry(Ci[x], 1, 1, L[Ci[x]], Cj[y], Cj[x]));
}
void Precalc()
{
for(int i = 1; (1 << i) <= N; i++)
for(int j = 1; j <= N; j++)
A[i][j] = A[i - 1][A[i - 1][j]];
for(int i = 1; i <= K; i++)
for(int j = 0; j <= 2 * L[i] + 2; j++)
AIT[i].push_back(0);
for(int i = 1; i <= N; i++)
Update(Ci[i], 1, 1, L[Ci[i]], Cj[i], Val[i]);
}
int main()
{
fin >> N >> M;
for(int i = 1; i <= N; i++)
fin >> Val[i];
for(int i = 1, a, b; i < N; i++)
{
fin >> a >> b;
G[a].push_back(b);
G[b].push_back(a);
}
DFS(1, 0); MakePath(1, 0, ++K); Precalc();
while(M--)
{
int p, x, y; fin >> p >> x >> y;
if(p == 0)
Update(Ci[x], 1, 1, L[Ci[x]], Cj[x], y);
else
{
int c = LCA(x, y);
fout << max(Solve(x, c), Solve(y, c)) << '\n';
}
}
fin.close();
fout.close();
return 0;
}