#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
int n,m,u[2005],v[2005],id[2005][2005];
queue<int>q;
struct Tree
{
	struct Edge
	{
		int to;
		int nxt;
	}e[4005];
	int edgenum,head[2005],pa[2005][2005],dep[2005][2005],a[2005][2005];
	bool flag[2005];
	void add(int u,int v)
	{
		e[++edgenum].to=v;
		e[edgenum].nxt=head[u];
		head[u]=edgenum;
	}
	void pre(int node,int r)
	{
		for(int hd=head[node];hd;hd=e[hd].nxt)
		{
			int to=e[hd].to;
			if(to==pa[r][node])continue;
			pa[r][to]=node;
			dep[r][to]=dep[r][node]+1;
			pre(to,r);
		}
	}
	void dfs(int r,int node,int x)
	{
//		printf("dfs(%d,%d,%d)\n",r,node,x);
		if(a[r][node])
		{
//			printf("a[%d][%d]=%d,id[%d][%d]=%d\n",r,node,a[r][node],r,node,id[r][node]);
			int i=id[r][node];
			a[r][node]=x;
			if(!flag[i])flag[i]=1,q.push(i);
			return;
		}
		a[r][node]=x;
		for(int hd=head[node];hd;hd=e[hd].nxt)
		{
			int to=e[hd].to;
			if(to==pa[r][node])continue;
			dfs(r,to,x);
		}
	}
	void solve(int x)
	{
		if(!x)return;
		if(id[u[x]][v[x]]&&id[u[x]][v[x]]!=x)
		{
			u[x]=v[x]=0;
			return;
		}
//		printf("solve(%d),(%d,%d)\n",x,u[x],v[x]);
//		printf("%d\n",a[13][16]);
		id[u[x]][v[x]]=id[v[x]][u[x]]=0;
		while((a[u[x]][v[x]]&&a[u[x]][v[x]]!=v[x])||(a[v[x]][u[x]]&&a[v[x]][u[x]]!=u[x]))
		{
//			printf("a[%d][%d]:%d %d\n",u[x],v[x],a[u[x]][v[x]],a[v[x]][u[x]]);
			if(a[u[x]][v[x]]&&a[u[x]][v[x]]!=v[x])u[x]=a[u[x]][v[x]];
			if(a[v[x]][u[x]]&&a[v[x]][u[x]]!=u[x])v[x]=a[v[x]][u[x]];
//			printf("%d %d\n",u[x],v[x]);
		}
		if(u[x]==v[x]||id[u[x]][v[x]])
		{
			u[x]=v[x]=0;
			return;
		}
		int a=u[x],b=v[x];
//		printf("%d %d\n",u[x],v[x]);
		id[a][b]=id[b][a]=x;
		dfs(a,b,b);
		dfs(b,a,a);
	}
	void work(int st)
	{
		q.push(st);
		flag[st]=1;
		while(!q.empty())
		{
			int node=q.front();
			q.pop();
			solve(node);
			flag[node]=0;
		}
	}
}T;
struct Edge
{
	int to;
	int nxt;
}e[4005];
int edgenum,head[2005],ans;
void add(int u,int v)
{
	e[++edgenum].to=v;
	e[edgenum].nxt=head[u];
	head[u]=edgenum;
}
void dfs(int r,int node)
{
	for(int hd=head[node];hd;hd=e[hd].nxt)
	{
		int to=e[hd].to;
		if(T.dep[r][node]+T.dep[node][to]==T.dep[r][to])ans++,dfs(r,to);
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<n;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		T.add(u,v);
		T.add(v,u);
	}
	for(int i=1;i<=n;i++)T.pre(i,i);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&u[i],&v[i]);
		T.work(i);
		if(!u[i])i--,m--;
//		for(int j=1;j<=i;j++)printf("(%d,%d)",u[j],v[j]);
//		printf("\n");
	}
	for(int i=1;i<=m;i++)
	{
//		printf("(%d,%d) ",u[i],v[i]);
		add(u[i],v[i]);
		add(v[i],u[i]);
	}
//	printf("\n");
	for(int i=1;i<=n;i++)dfs(i,i);
	printf("%d\n",ans/2);
	return 0;
}