#include <bits/stdc++.h>
using namespace std;
#define FILE_IO
const int buffer = 1 << 13;
int cnt = buffer - 1;
char buff[buffer + 5];
char gchar()
{
if(++cnt == buffer)
{
cnt = 0;
fread(buff, buffer, 1, stdin);
}
return buff[cnt];
}
int gint()
{
char ch = gchar();
while(ch < '0' || '9' < ch)
ch = gchar();
int x = 0;
while('0' <= ch && ch <= '9')
{
x = x * 10 + ch - '0';
ch = gchar();
}
return x;
}
int N, M, ans;
int Nlant[100005];
int hvy[100005], val[100005];
int h[100005], poseul[100005];
int E, rmq[200005][18], p2[200005];
int L, lant[100005], fth[100005], pos[100005];
vector <int> edg[100005];
vector <int> lnt[100005];
void DFS(int nod, int _fth)
{
fth[nod] = _fth;
h[nod] = h[_fth] + 1;
E++;
poseul[nod] = E;
rmq[E][0] = nod;
hvy[nod] = 1;
int nodmax = 0;
for(vector <int> :: iterator it = edg[nod].begin(); it != edg[nod].end(); it++)
{
int nxt = *it;
if(nxt == _fth) continue;
DFS(nxt, nod);
rmq[++E][0] = nod;
hvy[nod] += hvy[nxt];
if(hvy[nxt] > hvy[nodmax]) nodmax = nxt;
}
if(nodmax == 0)
{
lnt[++L].push_back(nod);
lant[nod] = L;
}
else
{
lant[nod] = lant[nodmax];
lnt[ lant[nod] ].push_back(nod);
}
}
int minh(int a, int b)
{
if(h[a] < h[b]) return a;
return b;
}
bool cmph(int a, int b)
{
return h[a] > h[b];
}
int LCA(int a, int b)
{
int st = poseul[a];
int dr = poseul[b];
if(st > dr) swap(st, dr);
int pw = p2[dr - st + 1];
return minh(rmq[st][pw], rmq[dr - (1 << pw) + 1][pw]);
}
int *aint[100005];
void B(int ind, int nod, int st, int dr)
{
if(st == dr)
{
aint[ind][nod] = val[ lnt[ind][st - 1] ];
return;
}
int mij = st + (dr - st) / 2;
B(ind, nod * 2, st, mij);
B(ind, nod * 2 + 1, mij + 1, dr);
aint[ind][nod] = max(aint[ind][nod * 2], aint[ind][nod * 2 + 1]);
}
void U(int ind, int nod, int st, int dr, int pos, int val)
{
if(st == dr)
{
aint[ind][nod] = val;
return;
}
int mij = st + (dr - st) / 2;
if(pos <= mij)
U(ind, nod * 2, st, mij, pos, val);
else
U(ind, nod * 2 + 1, mij + 1, dr, pos, val);
aint[ind][nod] = max(aint[ind][nod * 2], aint[ind][nod * 2 + 1]);
}
void Q(int ind, int nod, int st, int dr, int sti, int dri)
{
if(sti <= st && dr <= dri)
{
ans = max(ans, aint[ind][nod]);
return;
}
int mij = st + (dr - st) / 2;
if(sti <= mij)
Q(ind, nod * 2, st, mij, sti, dri);
if(mij < dri)
Q(ind, nod * 2 + 1, mij + 1, dr, sti, dri);
}
int Query(int x, int y)
{
if(lant[x] == lant[y])
{
int posx = pos[x];
int posy = pos[y];
if(posx > posy) swap(posx, posy);
ans = 0;
Q(lant[x], 1, 1, Nlant[ lant[x] ], posx, posy);
return ans;
}
int n = lnt[ lant[x] ].size();
ans = 0;
Q(lant[x], 1, 1, Nlant[ lant[x] ], pos[x], Nlant[ lant[x] ]);
int ans1 = ans;
int ansnxt = Query(fth[ lnt[ lant[x] ][n - 1] ], y);
return max(ans1, ansnxt);
}
int main()
{
#ifdef FILE_IO
freopen("heavypath.in", "r", stdin);
freopen("heavypath.out", "w", stdout);
#endif
N = gint();
M = gint();
for(int i = 1; i <= N; i++)
val[i] = gint();
for(int i = 1; i < N; i++)
{
int x, y;
x = gint();
y = gint();
edg[x].push_back(y);
edg[y].push_back(x);
}
DFS(1, 0);
for(int i = 2; i <= E; i++)
{
p2[i] = p2[i - 1];
if((2 << p2[i]) == i)
p2[i]++;
}
for(int j = 1; (1 << j) <= E; j++)
for(int i = 1; i + (1 << j) - 1 <= E; i++)
rmq[i][j] = minh(rmq[i][j - 1], rmq[i + (1 << (j - 1))][j - 1]);
for(int i = 1; i <= L; i++)
{
Nlant[i] = lnt[i].size();
sort(lnt[i].begin(), lnt[i].end(), cmph);
for(int j = 0; j < lnt[i].size(); j++)
{
int nod = lnt[i][j];
pos[nod] = j + 1;
}
aint[i] = new int[ Nlant[i] * 4 ];
B(i, 1, 1, Nlant[i]);
}
while(M--)
{
int op, x, y;
op = gint();
x = gint();
y = gint();
if(op == 0)
{
int lantx = lant[x];
int posx = pos[x];
U(lantx, 1, 1, Nlant[lantx], posx, y);
}
else
{
int lca = LCA(x, y);
int q1 = Query(x, lca);
int q2 = Query(y, lca);
printf("%d\n", max(q1, q2));
}
}
return 0;
}