#include <fstream>
#include <algorithm>
#include <vector>
#include <utility>;
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
vector <int> V[100005],L[100005];
int aint[400005];
int N,M,LN,narb;
int v[100005],w[100005],cel[100005],niv[100005],diml[100005],tatal[100005],pozi[100005],pozl[100005],lniv[100005];
bool viz[100005];
void DFS(int x)
{ w[x]=1; viz[x]=1;
vector <int>::iterator it;
bool frunza=1;
int submax=-1;
for(it=V[x].begin();it!=V[x].end();++it)
if(!viz[*it])
{ frunza=0;
niv[*it]=niv[x]+1;
DFS(*it);
if(submax==-1 )
submax=*it;
else if(w[submax] <w[*it])
submax=*it;
w[x]+=w[*it];
}
if(frunza)
{ cel[x]=++LN;
diml[LN]=1;
L[LN].push_back(x);
return;
}
cel[x]=cel[submax];
++diml[cel[x]];
L[cel[x]].push_back(x);
for(it=V[x].begin();it!=V[x].end();++it)
if((*it)!=submax && niv[*it]>niv[x])
{tatal[cel[*it]]=x;
lniv[cel[*it]]=niv[x];
}
}
void update(int nd,int val)
{int po=narb-1,f,t;
po+=pozl[cel[nd]];
po+=pozi[nd]-1;
aint[po]=val;
f=po; t=f/2;
while(f>1)
{ if(f%2) --f;
aint[t]=max(aint[f],aint[f+1]);
f=t;
t=t/2;
}
}
int query(int nd,int x,int y,int st,int dr)
{
if(x==st && y==dr)
return aint[nd];
int mijl=(st+dr)/2;
if(y<=mijl)
return query(nd*2,x,y,st,mijl);
else
if(x>mijl)
return query(nd*2+1,x,y,mijl+1,dr);
else
{
int sol=query(nd*2,x,mijl,st,mijl);
sol=max(sol,query(nd*2+1,mijl+1,y,mijl+1,dr));
return sol;
}
}
int main()
{
fin>>N>>M;
int i,x,y,ct,pc,t,sol;
for(i=1;i<=N;++i)
fin>>v[i];
for(i=1;i<N;++i)
{ fin>>x>>y;
V[x].push_back(y);
V[y].push_back(x);
}
DFS(1);
narb=1;
while(narb<N) narb*=2;
ct=0;
vector <int> ::iterator it;
for(i=1;i<=LN;++i)
{ ++ct; pc=1;
pozl[i]=ct;
reverse(L[i].begin(),L[i].end());
for(it=L[i].begin();it!=L[i].end();++it)
{
pozi[*it]=pc++;
aint[narb-1+ct]=v[*it];
++ct;
}
--ct;
}
for(i=narb-1;i>=1;--i)
aint[i]=max(aint[i*2],aint[i*2+1]);
return 0;
}