#define NMAX 100005
#include <fstream>
#include <vector>
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
int n, m, a, b, idxl = 1, iddfs = 1, t, added;
int valori[NMAX], tati[NMAX], interv[4*NMAX], adancime[NMAX], subarbore[NMAX];
int label_lant[NMAX], idfs[NMAX];
vector<int> graph[NMAX];
void dfs(int nod, int tata, int nivel)
{
tati[nod] = tata;
adancime[nod] = nivel;
subarbore[nod] = 1;
for(auto &v:graph[nod])
if(v != tata)
{
dfs(v, nod, nivel+1);
subarbore[nod] += subarbore[v];
}
}
vector<int> orddfs;
void form_labels(int nod, int tata, int labelact)
{
idfs[nod] = iddfs++;
label_lant[nod] = labelact;
orddfs.push_back(nod);
int biggest_child = -1;
for(auto &v:graph[nod])
if(v != tata)
{
if(biggest_child == -1 || (biggest_child != -1 && subarbore[v] > subarbore[biggest_child]))
biggest_child = v;
}
if(biggest_child != -1)
{
form_labels(biggest_child, nod, labelact);
}
for(auto &v:graph[nod])
if(v != biggest_child && v != tata)
form_labels(v, nod, v);
}
void afis(int a[])
{
for(int i = 1; i <= n; ++i)
g<<a[i]<<" ";
g<<'\n';
}
void form_interv(int poz_inter, int st, int dr, int val, int poz)
{
if(st == dr)
{
interv[poz_inter] = val;
return;
}
int mijl = (st + dr)/2;
if(poz <= mijl)
form_interv(2*poz_inter, st, mijl, val, poz);
else
form_interv(2*poz_inter + 1, mijl+1, dr, val, poz);
interv[poz_inter] = max(interv[2*poz_inter], interv[2*poz_inter + 1]);
}
int query(int pozint, int sti, int dri, int st, int dr)
{
if(st <= sti && dri <= dr)
return interv[pozint];
int mijl = (sti + dri)/2;
int val1 = -1, val2 = -1;
if(mijl >= dr)
{
val1 = query(2*pozint, sti, mijl, st, dr);
}
else if(mijl <= st)
{
val2 = query(2*pozint+1, mijl+1, dri, st, dr);
}
else{
val1 = query(2*pozint, sti, mijl, st, dr);
val2 = query(2*pozint+1, mijl, dri, st, dr);
}
return max(val1, val2);
}
int findmax(int x, int y)
{
if(label_lant[x] == label_lant[y])
{
if(idfs[x] > idfs[y])
swap(x, y);
return query(1, 1, n, idfs[x], idfs[y]);
}
else{
if(label_lant[x] < label_lant[y])
swap(x, y);
return max(query(1, 1, n, idfs[label_lant[x]], idfs[x]), findmax(tati[label_lant[x]], y));
}
}
void update(int nod, int st, int dr, int indexv, int with)
{
if(st == dr)
{
interv[nod] = with;
return;
}
int mijl = (st + dr)/2;
if(indexv <= mijl)
update(2*nod, st, mijl, indexv, with);
else update(2*nod+1, mijl+1, dr, indexv, with);
interv[nod] = max(interv[2*nod], interv[2*nod+1]);
}
void read()
{
f>>n>>m;
for(int i = 1; i <= n; ++i)
f>>valori[i];
for(int i = 1; i < n; ++i)
{
f>>a>>b;
graph[a].push_back(b);
graph[b].push_back(a);
}
dfs(1, 0, 1);
form_labels(1, 0, 1);
for(int i = 1; i <= n; ++i)
form_interv(1, 1, n, valori[i], idfs[i]);
//afis(label_lant);
//afis(tati);
//afis(interv);
for(int i = 1; i <= m; ++i)
{
f>>t>>a>>b;
if(t == 0)
update(1, 1, n, idfs[a], b);
else g<<findmax(a, b)<<"\n";
}
}
int main()
{
read();
return 0;
}