#include <iostream>
#include <cstdio>
#include <vector>
#define N 100
using namespace std;
int n,m,x,y,k,c;
int val[N],d[N],t[N], lant[N], pozitie[N];
vector <int> g[N];
vector <int> lanturi[N];
struct Arbint{
int *arbint;
int len;
Arbint(){
len = 0;
}
Arbint(int l){
len = lanturi[l].size()-1;
arbint = new int[4*len];
construieste(1,len,1,l);
}
void construieste(int st, int dr, int pos, int l){
if(st==dr){
arbint[pos] = val[lanturi[l][st]];
return ;
}
int mij = (st+dr)/2;
construieste(st,mij,2*pos,l);
construieste(mij+1,dr,2*pos+1,l);
arbint[pos] = max(arbint[2*pos],arbint[2*pos+1]);
}
void actualizare(int loc, int v){
actualizare(loc,v,1,len,1);
}
void actualizare(int loc, int v, int st, int dr, int pos){
if(st==dr){
arbint[pos] = v;
return;
}
int mij = (st+dr)/2;
if(loc<=mij)
actualizare(loc,v,st,mij,2*pos);
else
actualizare(loc,v,mij+1,dr,2*pos+1);
arbint[pos] = max(arbint[2*pos],arbint[2*pos+1]);
}
int cautare(int qst, int qdr){
return cautare(qst,qdr,1,len,1);
}
int cautare(int qst, int qdr, int st, int dr, int pos){
if(qst<=st && dr<=qdr)
return arbint[pos];
int mij = (st+dr)/2;
if(qdr<=mij)
return cautare(qst,qdr,st,mij,2*pos);
if(mij<qst)
return cautare(qst,qdr,mij+1,dr,2*pos+1);
return max(cautare(qst,qdr,st,mij,2*pos),
cautare(qst,qdr,mij+1,dr,2*pos+1));
}
}arbore[N];
int dfs(int nod, int niv){
d[nod] = niv;
int w = 1, fmax = 0, next;
for(int i : g[nod])
if(!d[i]){
t[i] = nod;
int loc = dfs(i,niv+1);
w+=loc;
if(loc>fmax){
fmax = loc;
next = lant[i];
}
}
if(w==1){
lanturi[k].push_back(-1);
lanturi[k].push_back(nod);
lant[nod] = k++;
pozitie[nod]=1;
}else{
pozitie[nod] = lanturi[next].size();
lanturi[next].push_back(nod);
lant[nod] = next;
}
return w;
}
int cauta(int st, int dr){
if(lant[st]==lant[dr])
return arbore[lant[st]].cautare(min(pozitie[st],pozitie[dr]),
max(pozitie[st],pozitie[dr]));
if(d[lanturi[lant[st]].back()]<d[lanturi[lant[dr]].back()])
return max(cauta(st,t[lanturi[lant[dr]].back()]),
arbore[lant[dr]].cautare(pozitie[dr],arbore[lant[dr]].len));
return cauta(dr,st);
}
int main()
{
freopen("heavypath.in","r",stdin);
freopen("heavypath.out","w",stdout);
scanf("%d%d", &n,&m);
for(int i = 1; i <= n; ++i)
scanf("%d", &val[i]);
for(int i = 1; i < n; ++i){
scanf("%d%d", &x,&y);
g[x].push_back(y);
g[y].push_back(x);
}
dfs(1,1);
for(int i = 0; i < k; ++i)
arbore[i] = Arbint(i);
for(int i = 0; i < m; ++i){
scanf("%d%d%d", &c,&x,&y);
if(c==0){
arbore[lant[x]].actualizare(pozitie[x],y);
}else{
cout<<cauta(x,y)<<"\n";
}
}
return 0;
}