#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#define pb push_back
using namespace std;
ifstream fin ("heavypath.in");
ofstream fout ("heavypath.out");
const int Nmax=1e5+5, Pmax=(1<<17), Vmax=2e6+5;
int n, q;
struct node{
int v, w, ind, indc, h, p;
vector<int> ad;
};
struct AINT{
vector<int> v;
void build(int n){
v.resize(n, -1);
}
void _update(int nod, int l, int r, int pos, int val){
if (l==r){
v[nod]=val;
return;
}
int mij=(l+r)/2;
if (pos<=mij)
_update(nod*2, l, mij, pos, val);
else _update(nod*2+1, mij+1, r, pos, val);
v[nod]=max(v[nod*2], v[nod*2+1]);
}
void update(int pos, int val){
_update(1, 0, Pmax, pos, val);
}
int _querry(int nod, int l, int r, int ql, int qr){
if (qr<l || r<ql)
return -1;
if (ql<=l && r<=qr)
return v[nod];
int mij=(l+r)/2;
return max(_querry(nod*2, l, mij, ql, qr), _querry(nod*2+1, mij+1, r, ql, qr));
}
int querry(int l, int r){
return _querry(1, 0, Pmax, l, r);
}
};
struct HeavyPath{
vector<node> V;
vector<int> fchain;
AINT aint;
HeavyPath(int n){
V.resize(n);
}
void _get_w(int nod, int p, int h){
V[nod].h=h;
V[nod].p=p;
for (auto it:V[nod].ad)
if (it!=p){
_get_w(it, nod, h+1);
V[nod].w+=V[it].w;
}
V[nod].w++;
}
void _build_chain(int nod, int p, int &time, int &chain){
if (fchain.size()==chain)
fchain.pb(nod);
V[nod].ind=time++;
V[nod].indc=chain;
int mxw=0, mxi=-1;
for (auto it:V[nod].ad)
if (it!=p && mxw<V[it].w){
mxw=V[it].w;
mxi=it;
}
if (mxi!=-1){
_build_chain(mxi, nod, time, chain);
for (auto it:V[nod].ad)
if (it!=p && it!=mxi)
_build_chain(it, nod, time, ++chain);
}
}
inline void partition(){
_get_w(0, -1, 0);
int time=0, chain=0;
_build_chain(0, -1, time, chain);
aint.build(2*Pmax);
for (int i=0; i<n; i++)
aint.update(V[fchain[V[i].indc]].ind+V[i].h-V[fchain[V[i].indc]].h, V[i].v);
}
inline void update(int pos, int val){
V[pos].v=val;
aint.update(V[fchain[V[pos].indc]].ind+V[pos].h-V[fchain[V[pos].indc]].h, V[pos].v);
}
int querry(int a, int b){
int ra=fchain[V[a].indc];
int rb=fchain[V[b].indc];
int mx=-1;
while (ra!=rb){
if (V[ra].h<V[rb].h){
swap(a, b);
swap(ra, rb);
}
mx=max(mx, aint.querry(V[ra].ind, V[ra].ind+V[a].h-V[ra].h));
a=V[ra].p;
ra=fchain[V[a].indc];
}
if (V[a].h>V[b].h){
swap(a, b);
swap(ra, rb);
}
mx=max(mx, aint.querry(V[ra].ind+V[a].h-V[ra].h, V[rb].ind+V[b].h-V[rb].h));
return mx;
}
};
int main(){
fin>>n>>q;
HeavyPath arb(n);
for (int i=0; i<n; i++)
fin>>arb.V[i].v;
int a, b;
for (int i=0; i<n-1; i++){
fin>>a>>b;
a--; b--;
arb.V[a].ad.pb(b);
arb.V[b].ad.pb(a);
}
arb.partition();
int t, x, y;
for (int i=0; i<q; i++){
fin>>t>>x>>y;
if (t==0){
x--;
arb.update(x, y);
}
else{
x--; y--;
fout<<arb.querry(x, y)<<'\n';
}
}
return 0;
}