type ref=^nod;
nod=record
nr:longint;
adr:ref;
end;
var arb,lanturi:array[0..100005] of ref;
t:array[0..17,0..100005] of longint;
v,poz,path,tata,len,arbpoz,lev:array[0..100005] of longint;
arbint:array[0..400005] of longint;
n,m,i,x,y,nrl,j,max,max2,val,contor,t2,z,left:longint;
u:ref;
f,g:text;
procedure df(nod,nivel:longint;var rang:longint);
var u:ref;
max,temp:longint;
begin
lev[nod]:=nivel;
u:=arb[nod];
rang:=1;
max:=0;
while u<>nil do
begin
if u^.nr<>t[0,nod] then
begin
inc(rang);
t[0,u^.nr]:=nod;
df(u^.nr,nivel+1,temp);
if temp>max then
begin
max:=temp;
path[nod]:=path[u^.nr];
end;
tata[path[u^.nr]]:=nod;
end;
u:=u^.adr;
end;
if rang=1 then
begin
inc(nrl);
len[nrl]:=1;
new(lanturi[nrl]);
lanturi[nrl]^.nr:=nod;
lanturi[nrl]^.adr:=nil;
path[nod]:=nrl;
end
else
begin
new(u);
u^.nr:=nod;
u^.adr:=lanturi[path[nod]];
lanturi[path[nod]]:=u;
inc(len[path[nod]]);
end;
end;
procedure update(p,a,b,nod:longint);
var mid:longint;
begin
if a=b then
begin
arbint[left+nod]:=val;
if left+nod>max2 then
max2:=left+nod;
exit;
end;
mid:=a+(b-a) shr 1;
if p<=mid then
update(p,a,mid,nod shl 1)
else
update(p,mid+1,b,(nod shl 1)+1);
if arbint[left+(nod shl 1)]>arbint[left+(nod shl 1)+1] then
arbint[left+nod]:=arbint[left+(nod shl 1)]
else
arbint[left+nod]:=arbint[left+(nod shl 1)+1];
end;
function minim(a,b:longint):longint;
begin
if a<b then
minim:=a
else
minim:=b;
end;
function maxim(a,b:longint):longint;
begin
if a>b then
maxim:=a
else
maxim:=b;
end;
function query_ai(q1,q2,a,b,nod:longint):longint;
var mid,temp,temp2:longint;
begin
if (q1<=a) and (q2>=b) then
query_ai:=arbint[left+nod]
else
begin
mid:=a+(b-a) shr 1;
if q1<=mid then
temp:=query_ai(q1,minim(mid,q2),a,mid,nod shl 1)
else
temp:=0;
if q2>mid then
temp2:=query_ai(maxim(mid+1,q1),q2,mid+1,b,(nod shl 1)+1)
else
temp2:=0;
if temp>temp2 then
query_ai:=temp
else
query_ai:=temp2;
end;
end;
function lca(nod1,nod2:longint):longint;
var aux,pow,q:longint;
begin
if lev[nod1]>lev[nod2] then
begin
aux:=nod1;
nod1:=nod2;
nod2:=aux;
end;
if lev[nod1]<lev[nod2] then
begin
pow:=1;
q:=0;
while pow shl 1<=lev[nod2]-1 do
begin
pow:=pow shl 1;
inc(q);
end;
while lev[nod1]<lev[nod2] do
begin
if lev[t[q,nod2]]>=lev[nod1] then
nod2:=t[q,nod2];
dec(q);
end;
end;
if nod1=nod2 then
begin
lca:=nod1;
exit;
end;
if (nod1=1) or (nod2=1) then
begin
lca:=1;
exit;
end;
if t[0,nod1]<>t[0,nod2] then
begin
pow:=1;
q:=0;
while pow shl 1<=lev[nod1]-2 do
begin
pow:=pow shl 1;
inc(q);
end;
while t[0,nod1]<>t[0,nod2] do
begin
if t[q,nod1]<>t[q,nod2] then
begin
nod1:=t[q,nod1];
nod2:=t[q,nod2];
end;
dec(q);
end;
end;
lca:=t[0,nod1];
end;
function query(stramos,nod:longint):longint;
var ret,temp:longint;
begin
ret:=v[nod];
while stramos<>nod do
if path[stramos]=path[nod] then
begin
left:=arbpoz[path[nod]];
temp:=query_ai(poz[stramos],poz[nod],1,len[path[nod]],1);
if temp>ret then
query:=temp
else
query:=ret;
exit;
end
else
begin
left:=arbpoz[path[nod]];
temp:=query_ai(1,poz[nod],1,len[path[nod]],1);
if temp>ret then
ret:=temp;
nod:=tata[path[nod]];
if v[nod]>ret then
ret:=v[nod];
end;
query:=ret;
end;
begin
assign(f,'heavypath.in');
assign(g,'heavypath.out');
reset(f);rewrite(g);
readln(f,n,m);
for i:=1 to n do
read(f,v[i]);
for i:=1 to n-1 do
begin
readln(f,x,y);
new(u);
u^.nr:=y;
u^.adr:=arb[x];
arb[x]:=u;
new(u);
u^.nr:=x;
u^.adr:=arb[y];
arb[y]:=u;
end;
df(1,1,x);
tata[path[1]]:=0;
for i:=1 to nrl do
begin
arbpoz[i]:=max;
u:=lanturi[i];
j:=0;
while u<>nil do
begin
inc(j);
poz[u^.nr]:=j;
val:=v[u^.nr];
left:=max;
update(j,1,len[i],1);
u:=u^.adr;
end;
max:=max2;
end;
i:=1;
while 1 shl i<n do
begin
for j:=1 to n do
t[i,j]:=t[i-1,t[i-1,j]];
inc(i);
end;
for contor:=1 to m do
begin
readln(f,t2,x,y);
if t2=1 then
begin
z:=lca(x,y);
max:=query(z,x);
max2:=query(z,y);
if max>max2 then
writeln(g,max)
else
writeln(g,max2);
end
else
begin
v[x]:=y;
val:=y;
left:=arbpoz[path[x]];
update(poz[x],1,len[path[x]],1);
end;
end;
close(f);close(g);
end.