/*
    神奇!
    题意:给出一棵树,再给出M条新边,问删除一条树边以及一条新边,使之至少变为两部分的方案数

    对于新边(a,b),会在a->LCA(a,b)->b这里形成一个环,所以删除新边(a,b)以及这个环上的没有被其他环覆盖的边
    即可分成两部分。所以问题转化为求每条边被环覆盖的次数
    设dp[x]表示x所在的父边被覆盖的次数
    引进一条新边(a,b)后,dp[a]++,dp[b]++
    而这个环上的其他边的统计可以用treeDP解决,即for(v)
                                                      dp[u]+=dp[v]
    注意到LCA(a,b)的父边是不在环上的,所以每次引进新边(a,b),dp[LCA[a,b]]-=2
    最后,if(dp[i]==1)ans++        删除该边及覆盖它的那个环
           if(dp[i]==0)ans+=M  表明这条树边是桥,删除它及任意一条新边都可以

    不明白为什么跟别人的差了300多ms
    跟3694有一点点类似,新加入的边都是在a->LCA(a,b)->b形成环
*/

#include
<cstdio>
#include
<cstring>
#include
<cmath>
#include
<algorithm>
using namespace std;

const int MAXN = 100005;

struct Node
{
    
int v,next;
}
nodes[2*MAXN];

int N,M,alloc,done;
int G[MAXN],dp[MAXN];
int F[2*MAXN],B[2*MAXN],pos[MAXN];
int rmq[MAXN*2][20];

void add(int a,int b)
{
    nodes[
++alloc].v=b,nodes[alloc].next=G[a];
    G[a]
=alloc;
}

void dfs(int u,int p,int dep)
{
    F[
++done]=u,B[done]=dep;
    pos[u]
=done;
    
for(int son=G[u];son;son=nodes[son].next){
        
int v=nodes[son].v;
        
if(v==p)continue;
        dfs(v,u,dep
+1);
        F[
++done]=u,B[done]=dep;
    }

}

void initRMQ()
{
    
for(int i=1;i<=done;i++)rmq[i][0]=i;
    
for(int j=1;(1<<j)<=done;j++)
        
for(int i=1;i+(1<<j)-1<=done;i++)
            
if(B[rmq[i][j-1]]<B[rmq[i+(1<<(j-1))][j-1]])rmq[i][j]=rmq[i][j-1];
            
else rmq[i][j]=rmq[i+(1<<(j-1))][j-1];
}

int LCA(int a,int b)
{
    a
=pos[a],b=pos[b];
    
if(a>b)swap(a,b);
    
int k=log(1.0+b-a)/log(2.0);
    
if(B[rmq[a][k]]<B[rmq[b-(1<<k)+1][k]])return F[rmq[a][k]];
    
else return F[rmq[b-(1<<k)+1][k]];
}

void treeDP(int u,int p)
{
    
for(int son=G[u];son;son=nodes[son].next){
        
int v=nodes[son].v;
        
if(v==p)continue;
        treeDP(v,u);
        dp[u]
+=dp[v];
    }

}

int main()
{
    
while(~scanf("%d%d",&N,&M)){
        memset(G
+1,0,sizeof(int)*N);
        memset(dp
+1,0,sizeof(int)*N);
        done 
= alloc = 0;
        
int a,b;
        
for(int i=1;i<N;i++){
            scanf(
"%d%d",&a,&b);
            add(a,b);
            add(b,a);
        }

        dfs(
1,1,0);
        initRMQ();
        
for(int i=1;i<=M;i++){
            scanf(
"%d%d",&a,&b);
            dp[a]
++,dp[b]++;
            dp[LCA(a,b)]
-=2;
        }

        treeDP(
1,1);
        
int ans=0;
        
for(int i=2;i<=N;i++){
            
if(dp[i]==0)ans+=M;
            
if(dp[i]==1)ans++;
        }

        printf(
"%d\n",ans);
    }

    
return 0;
}



/*
    参考ST版的
    不过这个会快点
*/

#include
<cstdio>
#include
<cstring>

const int MAXN = 100005;//神奇,改为100010就wa.  

struct Node
{
    
int v,w,next;
}
nodes[4*MAXN];

int dp[MAXN],G[MAXN],Q[MAXN];
int fa[MAXN],ans[MAXN];
int N,M,alloc;
bool vi[MAXN];

void add1(int a,int b)
{
    alloc
++;
    nodes[alloc].v
=b,nodes[alloc].next=G[a];
    G[a]
=alloc;
}

void add2(int a,int b,int c)
{
    alloc
++;
    nodes[alloc].v
=b,nodes[alloc].w=c;
    nodes[alloc].next
=Q[a];
    Q[a]
=alloc;
}

int find(int a)
{
    
if(fa[a]==a)return a;
    
return fa[a]=find(fa[a]);
}


void Tarjan(int u)
{
    vi[u]
=1;
    
for(int son=Q[u];son;son=nodes[son].next){
        
int v=nodes[son].v,id=nodes[son].w;
        
if(vi[v])ans[id]=find(v);
    }

    
for(int son=G[u];son;son=nodes[son].next){
        
int v=nodes[son].v;
        
if(!vi[v]){
            Tarjan(v);
            fa[v]
=u;
        }

    }

}

void treeDP(int u,int p)
{
    
for(int son=G[u];son;son=nodes[son].next){
        
int v=nodes[son].v;
        
if(v==p)continue;
        treeDP(v,u);
        dp[u]
+=dp[v];
    }

}


int main()
{
    
while(~scanf("%d%d",&N,&M)){
        memset(G
+1,0,sizeof(int)*N);
        memset(Q
+1,0,sizeof(int)*N);
        memset(dp
+1,0,sizeof(int)*N);
        memset(vi
+1,0,sizeof(int)*N);
        alloc
=0;
        
int a,b;
        
for(int i=1;i<=N;i++)fa[i]=i;
        
for(int i=1;i<N;i++){
            scanf(
"%d%d",&a,&b);
            add1(a,b);
            add1(b,a);
        }

        
for(int i=1;i<=M;i++){
            scanf(
"%d%d",&a,&b);
            add2(a,b,i);
            add2(b,a,i);
            dp[a]
++;
            dp[b]
++;
        }

        Tarjan(
1);
        
for(int i=1;i<=M;i++)
            dp[ans[i]]
-=2;
        treeDP(
1,1);
        
int ans=0;
        
for(int i=2;i<=N;i++){
            
if(dp[i]==0)ans+=M;
            
if(dp[i]==1)ans++;
        }

        printf(
"%d\n",ans);
    }

    
return 0;
}