思路:树链剖分
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const int N=1e5+50;
const int M=1e5+50;
const int Mod=1e9+7;
inline ll read(){
ll x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
ll n,k;
ll top[N],siz[N],dep[N],id[N],wt[N],fa[N],son[N],res;
ll head[N],cnt;
struct edge{
ll to,next;
}e[N<<1];
void add_edge(ll u,ll v){
++cnt;
e[cnt].to=v;
e[cnt].next=head[u];
head[u]=cnt;
}
void dfs1(ll u,ll p){
fa[u]=p;
dep[u]=dep[p]+1;
siz[u]=1;
int maxn=-1;
for(int i=head[u];i;i=e[i].next){
ll v=e[i].to;
if(v==p) continue;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[v]>maxn) son[u]=v,maxn=siz[v];
}
}
void dfs2(ll u,ll topf){
top[u]=topf;
++res;
id[u]=res;
wt[res]=0;
if(!son[u]) return;
dfs2(son[u],topf);
for(int i=head[u];i;i=e[i].next){
ll v=e[i].to;
if(v==fa[u]||v==son[u]) continue;
dfs2(v,v);
}
}
ll ans[N<<2],lazy[N<<2];
ll ls(ll p){return p<<1;}
ll rs(ll p){return p<<1|1;}
void push_up(ll p){ans[p]=max(ans[ls(p)],ans[rs(p)]);}
void build(ll p,ll l,ll r){
lazy[p]=0;
if(l==r){ans[p]=wt[l];return;}
ll mid=(l+r)>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
push_up(p);
}
void change(ll p,ll l,ll r,ll add){
ans[p]+=(r-l+1)*add;
lazy[p]+=add;
}
void push_down(ll p,ll l,ll r){
ll mid=(l+r)>>1;
change(ls(p),l,mid,lazy[p]);
change(rs(p),mid+1,r,lazy[p]);
lazy[p]=0;
}
void update(ll nx,ll ny,ll l,ll r,ll p,ll k){
if(nx<=l&&r<=ny){
lazy[p]+=k;
ans[p]+=(r-l+1)*k;
return;
}
push_down(p,l,r);
ll mid=(l+r)>>1;
if(nx<=mid) update(nx,ny,l,mid,ls(p),k);
if(ny>mid) update(nx,ny,mid+1,r,rs(p),k);
push_up(p);
}
ll query(ll nx,ll ny,ll l,ll r,ll p){
ll res=0;
if(nx<=l&&r<=ny) return ans[p];
push_down(p,l,r);
ll mid=(l+r)>>1;
if(nx<=mid) res=max(res,query(nx,ny,l,mid,ls(p)));
if(ny>mid) res=max(res,query(nx,ny,mid+1,r,rs(p)));
return res;
}
void update_range(ll x,ll y,ll k){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
update(id[top[x]],id[x],1,n,1,k);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
update(id[x],id[y],1,n,1,k);
}
int main()
{
n=read(),k=read();
for(int i=1;i<n;++i){
ll u=read(),v=read();
add_edge(u,v);
add_edge(v,u);
}
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
for(int i=1;i<=k;++i){
ll u=read(),v=read();
update_range(u,v,1);
}
printf("%lld\n",query(1,n,1,n,1));
return 0;
}