#include <bits/stdc++.h>
#define pb push_back
#define int long long
using namespace std;
const int N=1e5+5;
vector<int> g[N];
int val[N],sz[N],dep[N],par[N];
int paths=0;
int path[N],poz[N],len[N];
vector<vector<int>> v;
vector<int> dummy;
vector<vector<int>> aint;
void dfs(int node, int tata)
{
par[node]=tata;
if(tata!=0) dep[node]=dep[tata]+1;
int mx=0,best=-1;
sz[node]=1;
for(auto x:g[node])
{
if(x==tata) continue;
dfs(x,node);
if(sz[x]>=mx) best=x;
mx=max(mx,sz[x]);
sz[node]+=sz[x];
}
if(best==-1)
{
path[node]=++paths;
v.pb(dummy);
v[path[node]].pb(node);
return;
}
path[node]=path[best];
v[path[node]].pb(node);
}
void build(int i, int node, int l, int r)
{
if(l==r) {aint[i][node]=val[v[i][l]];return;}
int mij=(l+r)/2;
build(i,node*2,l,mij);
build(i,node*2+1,mij+1,r);
aint[i][node]=max(aint[i][node*2],aint[i][node*2+1]);
}
void update(int i, int node, int l, int r, int poz, int val)
{
if(l==r) {aint[i][node]=val;return;}
int mij=(l+r)/2;
if(poz<=mij) update(i,node*2,l,mij,poz,val);
else update(i,node*2+1,mij+1,r,poz,val);
aint[i][node]=max(aint[i][node*2],aint[i][node*2+1]);
}
int query(int i, int node, int l, int r, int ql, int qr)
{
if(ql<=l&&r<=qr) return aint[i][node];
int mij=(l+r)/2;
if(ql<=mij&&qr>=mij+1) return max(query(i,node*2,l,mij,ql,qr),query(i,node*2+1,mij+1,r,ql,qr));
else if(ql<=mij) return query(i,node*2,l,mij,ql,qr);
else return query(i,node*2+1,mij+1,r,ql,qr);
}
void decomp()
{
aint.pb(dummy);
for(int p=1;p<=paths;++p)
{
assert(p<v.size());
len[p]=v[p].size();
v[p].pb(-1);
reverse(v[p].begin(),v[p].end());
for(int i=1;i<=len[p];++i) poz[v[p][i]]=i;
aint.pb(dummy);
aint[p].resize(4*len[p]+5);
build(p,1,1,len[p]);
}
}
int getquery(int a, int b)
{
int ans=-1e18;
while(1)
{
if(dep[a]>dep[b]) swap(a,b);
if(path[a]==path[b]) return max(ans,query(path[a],1,1,len[path[a]],poz[a],poz[b]));
if(dep[v[path[a]][1]]>dep[v[path[b]][1]]) swap(a,b);
ans=max(ans,query(path[b],1,1,len[path[b]],1,poz[b]));
b=par[v[path[b]][1]];
}
}
signed main()
{
ifstream cin("heavypath.in");ofstream cout("heavypath.out");
int n,q;
cin>>n>>q;
for(int i=1;i<=n;++i) cin>>val[i];
for(int _=1;_<n;++_)
{
int uu,vv;cin>>uu>>vv;
g[uu].pb(vv);
g[vv].pb(uu);
}
v.pb(dummy);
dfs(1,0);
decomp();
while(q--)
{
int op;cin>>op;
if(op==0)
{
int x,y;cin>>x>>y;
update(path[x],1,1,len[path[x]],poz[x],y);
}
else
{
int l,r;cin>>l>>r;
cout<<getquery(l,r)<<'\n';
}
}
}