#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#define MAXN 100005
#define INFI 1000006
#define bol bool
using namespace std;
struct NOD{
int cost;
int last;
int adan;
int pozi;
int loca;
int fath;
bol hevy;
bol visi;
};
struct LFD{
int left;
int righ;
};
vector <int> graf[MAXN];
NOD poit[MAXN];
LFD stdr[MAXN];
int aint[MAXN*4];
int siru[MAXN];
int eule[MAXN*2];
int alca[MAXN*8];
int t;
int Min(int x,int y){
return x<y?x:y;
}
int Max(int x,int y){
return x>y?x:y;
}
int DFS(int node,int adan){
int ma,x,s,aux;
s=1;
ma=-1;
x=-1;
poit[node].adan=adan;
poit[node].visi=true;
poit[node].last=t;
eule[t++]=adan;
for(int neigh : graf[node]){
if(!poit[neigh].visi){
aux=DFS(neigh,adan+1);
poit[node].last=t;
eule[t++]=adan;
if(ma<aux){
ma=aux;
x=neigh;
}
s+=aux;
}
}
if(x!=-1){
poit[x].hevy=true;
}
return s;
}
void CreateLCA(int x,int y,int poz){
int mij;
if(x==y){
alca[poz]=eule[x];
return;
}
mij=(x+y)/2;
CreateLCA(x ,mij,poz*2 );
CreateLCA(mij+1,y ,poz*2+1);
alca[poz]=Min(alca[poz*2],alca[poz*2+1]);
}
int LCA(int x,int y,int i,int j,int poz){
int mij;
if(i<=x && y<=j){
return alca[poz];
}
if(y<i || j<x){
return INFI;
}
mij=(x+y)/2;
return Min(LCA(x ,mij,i,j,poz*2 ),
LCA(mij+1,y ,i,j,poz*2+1));
}
void MakeHeavyDecomp(int n){
int i,m,t,s,node;
m=0;
t=1;
for(i=1;i<=n;i++){
if(poit[i].hevy==0){
stdr[m].left=t;
s=1;
node=i;
while(s==1){
poit[node].loca=t;
siru[t++]=node;
poit[node].pozi=m;
s=0;
for(int neigh : graf[node]){
if(poit[neigh].hevy){
node=neigh;
s=1;
}
}
}
stdr[m].righ=t;
m++;
}
}
}
void CreateAINT(int x,int y,int poz){
int mij;
if(x==y){
aint[poz]=poit[siru[x]].cost;
return;
}
mij=(x+y)/2;
CreateAINT(x ,mij,poz*2 );
CreateAINT(mij+1,y ,poz*2+1);
aint[poz]=Max(aint[poz*2],aint[poz*2+1]);
}
int SearchAINT(int x,int y,int i,int j,int poz){
int mij;
if(i<=x && y<=j){
return aint[poz];
}
if(j<x || y<i){
return 0;
}
mij=(x+y)/2;
return Max(SearchAINT(x ,mij,i,j,poz*2 ),
SearchAINT(mij+1,y ,i,j,poz*2+1));
}
void UpdateAINT(int x,int y,int i,int val,int poz){
int mij;
if(x==i && i==y){
aint[poz]=val;
return;
}
if(i<x || y<i){
return;
}
mij=(x+y)/2;
UpdateAINT(x ,mij,i,val,poz*2 );
UpdateAINT(mij+1,y ,i,val,poz*2+1);
aint[poz]=Max(aint[poz*2],aint[poz*2+1]);
}
int main(){
int n,m,i,x,y,inter,st,dr,r,j,aux,last;
FILE *fin,*fout;
fin=fopen("heavypath.in","r");
fout=fopen("heavypath.out","w");
fscanf(fin,"%d%d",&n,&m);
for(i=1;i<=n;i++){
fscanf(fin,"%d",&poit[i].cost);
poit[i].fath=-1;
}
for(i=1;i<n;i++){
fscanf(fin,"%d%d",&x,&y);
poit[y].fath=x;
graf[x].push_back(y);
}
DFS(1,1);
CreateLCA(1,2*n-2,1);
MakeHeavyDecomp(n);
CreateAINT(1,n,1);
printf("last adan pozi loca fath hevy siru\n");
for(i=1;i<=n;i++){
printf("%4d %4d %4d %4d %4d %4d %4d\n", poit[i].last,
poit[i].adan,
poit[i].pozi,
poit[i].loca,
poit[i].fath,
poit[i].hevy,
siru[i]);
}
for(i=0;i<=2*n;i++){
printf("%d ",eule[i]);
}
for(i=0;i<m;i++){
fscanf(fin,"%d%d%d",&t,&x,&y);
if(t==0){
UpdateAINT(1,n,poit[x].loca,y,1);
}else{
st=poit[x].last;
dr=poit[y].last;
if(st>dr){
aux=dr;
dr=st;
st=aux;
}
inter=LCA(1,2*n-2,st,dr,1);
r=-1;
for(j=0;j<2;j++){
if(j==0){
last=x;
}else{
last=y;
}
while(poit[siru[stdr[poit[last].pozi].left]].adan>inter){
r=Max(r,SearchAINT(1,n,stdr[poit[last].pozi].left,poit[last].loca,1));
last=poit[siru[stdr[poit[last].pozi].left]].fath;
}
r=Max(r,SearchAINT(1,n,stdr[poit[last].pozi].left+inter-poit[stdr[poit[last].pozi].left].adan,poit[last].loca,1));
}
fprintf(fout,"%d\n",r);
}
}
fclose(fin);
fclose(fout);
return 0;
}