#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#define Nmax 100000
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
int V[Nmax+5];
int use[Nmax+5],niv[Nmax+5],L[Nmax+5],LD[Nmax+5],LP[Nmax+5],w[Nmax+5],LT[Nmax+5],LN[Nmax+5],AI[4*Nmax +5],NL,N,M;
vector <int> G[Nmax+5];
vector <int> P[Nmax+5];
void dfs(int nod){
use[nod]=1;
int frunza = 1, nh = -1;
for(int i=0;i<G[nod].size();i++){
int vecin = G[nod][i];
if(use[vecin]) continue;
frunza = 0;
niv[vecin] = niv[nod]+1;
dfs(vecin);
w[nod]+=w[vecin];
if(nh==-1)
nh = vecin;
else if(w[nh] < w[vecin])
nh = vecin;
}
if(frunza){
L[nod] = ++NL;
LD[NL] = 1;
P[NL].push_back(nod);
return;
}
L[nod] = L[nh];
++LD[L[nod]];
P[L[nod]].push_back(nod);
for(int i=0;i<G[nod].size();i++){
int vecin = G[nod][i];
if(vecin!=nh && niv[vecin]>=niv[nod]){
LT[L[vecin]] = nod;
LN[L[vecin]] = niv[nod];
}
}
}
void build(int nod,int st,int dr,int dec,int lant){
if(st==dr){
AI[nod + dec] = V[P[lant][st-1]];
return;
}
int mid = (st+dr)/2;
build(nod*2,st,mid,dec,lant);
build(nod*2+1,mid+1,dr,dec,lant);
AI[nod + dec] = max(AI[nod*2 + dec],AI[nod*2+1 + dec]);
}
void conf(){
niv[1]=1;
dfs(1);
for(int i=1;i<=NL;i++)
{
reverse(P[i].begin(),P[i].end());
if(i>1)
LP[i] = LP[i-1] + LD[i-1] *4;
build(1,1,LD[i],LP[i],i);
}
}
void update(int nod, int st, int dr, int poz, int val, int dec){
if(st == dr)
{
AI[nod + dec] = val;
return;
}
int mid = (st+dr)/2;
if(poz<=mid)
update(nod*2,st,mid,poz,val,dec);
else
update(nod*2+1,mid+1,dr,poz,val,dec);
AI[nod + dec] = max(AI[nod*2 + dec],AI[nod*2+1 + dec]);
}
int query(int nod,int st,int dr,int qst,int qdr,int dec){
if(qst<=st && dr<=qdr){
return AI[nod + dec];
}
int mid = (st+dr)/2;
int sol = 0;
if(qst<=mid)
sol = max(sol,query(nod*2,st,mid,qst,qdr,dec));
if(qdr>mid)
sol = max(sol,query(nod*2+1,mid+1,dr,qst,qdr,dec));
return sol;
}
void read(){
fin>>N>>M;
for(int i=1;i<=N;i++)
{
fin>>V[i];
}
for(int i=1;i<N;i++){
int x,y;
fin>>x>>y;
G[x].push_back(y);
G[y].push_back(x);
}
conf();
for(int l=1;l<=M;l++){
int t,x,y;
fin>>t>>x>>y;
if(!t)
update(1,1,LD[L[x]],niv[x] - LN[L[x]],y,LP[L[x]]);
else
{
int sol = 0;
while(1){
if(L[x] == L[y]){
if(niv[x]>niv[y])
swap(x,y);
sol = max(sol,query(1,1,LD[L[x]],niv[x] - LN[L[x]],niv[y] - LN[L[x]],LP[L[x]]));
break;
}
if(LN[L[x]]<LN[L[y]])
swap(x,y);
sol = max(sol,query(1,1,LD[L[x]],1,niv[x] - LN[L[x]],LP[L[x]]));
x = LT[L[x]];
}
fout<<sol<<"\n";
}
}
}
int main()
{
read();
return 0;
}