#include <bits/stdc++.h>
#define Nmax 100005
#define INF 1000000000
#define pb push_back
using namespace std;
int val[Nmax],lvl[Nmax],Father[Nmax],Wh[Nmax],nr;
int poz[Nmax],cnt[Nmax],n;
vector <int> L[Nmax],Lant[Nmax];
class Aint
{
public:
vector <int> aint;
inline void upd(int nod, int st, int dr, int p, int x)
{
if(st==dr)
{
aint[nod]=x; return;
}
int mij=((st+dr)>>1);
if(p<=mij) upd(2*nod,st,mij,p,x);
else upd(2*nod+1,mij+1,dr,p,x);
aint[nod]=max(aint[2*nod],aint[2*nod+1]);
}
inline int qry(int nod, int st, int dr, int x, int y)
{
if(st==x && y==dr) return aint[nod];
int mij=((st+dr)>>1);
if(y<=mij) return qry(2*nod,st,mij,x,y);
if(x>mij) return qry(2*nod+1,mij+1,dr,x,y);
return max(qry(2*nod,st,mij,x,mij),qry(2*nod+1,mij+1,dr,mij+1,y));
}
} v[Nmax];
inline void Dfs(int nod, int tata)
{
int node=0;
cnt[nod]=1;
for(auto it : L[nod])
{
if(it==tata) continue;
lvl[it]=lvl[nod]+1;
Dfs(it,nod);
if(cnt[it]>cnt[node]) node=it;
cnt[nod]+=cnt[it];
}
if(!node)
{
Wh[nod]=++nr; poz[nod]=1;
Lant[nr].pb(nod);
}
else
{
Wh[nod]=Wh[node]; poz[nod]=poz[node]+1;
Lant[Wh[nod]].pb(nod);
}
for(auto it : L[nod])
{
if(it==tata || it==node) continue;
Father[Wh[it]]=nod;
}
}
inline void Make_HPD()
{
for(int i=1;i<=nr;++i)
{
v[i].aint.resize(4*Lant[i].size()+2);
for(int j=0;j<Lant[i].size();++j) v[i].upd(1,1,Lant[i].size(),j+1,val[Lant[i][j]]);
}
}
int main()
{
int m,x,y,t,ans,i;
ifstream cin("heavypath.in");
ofstream cout("heavypath.out");
cin>>n>>m;
for(i=1;i<=n;++i) cin>>val[i];
for(i=1;i<n;++i)
{
cin>>x>>y;
L[x].pb(y); L[y].pb(x);
}
lvl[1]=1; Dfs(1,0);
Make_HPD();
while(m--)
{
cin>>t>>x>>y;
if(!t) v[Wh[x]].upd(1,1,Lant[Wh[x]].size(),poz[x],y);
else
{
ans=-INF;
while(Wh[x]!=Wh[y])
{
if(lvl[Father[Wh[x]]]<lvl[Father[Wh[y]]]) swap(x,y);
ans=max(ans,v[Wh[x]].qry(1,1,Lant[Wh[x]].size(),poz[x],Lant[Wh[x]].size()));
x=Father[Wh[x]];
}
ans=max(ans,v[Wh[x]].qry(1,1,Lant[Wh[x]].size(),min(poz[x],poz[y]),max(poz[x],poz[y])));
cout<<ans<<"\n";
}
}
return 0;
}