#include <bits/stdc++.h>
using namespace std;
template <typename T> void read(T &t) {
	t=0; char ch=getchar(); int f=1;
	while (ch<'0'||ch>'9') { if (ch=='-') f=-1; ch=getchar(); }
	do { (t*=10)+=ch-'0'; ch=getchar(); } while ('0'<=ch&&ch<='9'); t*=f;
}
int n,m;
struct node { int x,y; } e[2010];
namespace BF {
	vector<int> g[310];
	bool d[310][310];
	int dis[310][310];
	queue<node> q;
	void dfs(int u,int p,int S) {
		for (int i=0,v;i<g[u].size();i++) {
			v=g[u][i];
			if (v==p) continue;
			dis[S][v]=dis[S][u]+1;
			dfs(v,u,S);
		}
	}
	bool check(int x,int y,int z) {
		if (dis[x][y]+dis[y][z]==dis[x][z]) return 1;
		if (dis[x][z]+dis[z][y]==dis[x][y]) return 1;
		if (dis[y][x]+dis[x][z]==dis[y][z]) return 1;
		return 0;
	}
	void insert(int x,int y) {
		for (int z=1;z<=n;z++) {
			if (d[x][z]||z==x||z==y||!d[y][z]) continue;
			if (check(x,y,z)) q.push((node){x,z}),d[x][z]=d[z][x]=1;
		}
	}	
	void solve() {
		int x,y;
		for (int i=1;i<n;i++) {
			read(x); read(y);
			g[x].push_back(y);
			g[y].push_back(x);
		}
		for (int i=1;i<=m;i++) {
			read(x); read(y);
			d[x][y]=d[y][x]=1;
			q.push((node){x,y});
		}
		for (int i=1;i<=n;i++) dfs(i,0,i);
		while (!q.empty()) {
			x=q.front().x,y=q.front().y; q.pop();
			insert(x,y);
			insert(y,x);
		}
		m=0;
		for (int i=1;i<=n;i++)
		for (int j=i+1;j<=n;j++) m+=d[i][j];
		printf("%d\n",m);
		exit(0);
	}
};
namespace Lian {
	bool check() {
		for (int i=1;i<n;i++)
			if (e[i].y!=e[i].x+1) return 0;
		return 1;
	}
	int cnt;
	bool vis[2010];
	vector<int> g[2010];
	void dfs(int u) {
		if (vis[u]) return;
		vis[u]=1; cnt++;
		for (int i=0;i<g[u].size();i++) dfs(g[u][i]);
	}
	void solve() {
		int x,y;
		for (int i=1;i<=m;i++) {
			read(x); read(y);
			g[x].push_back(y); g[y].push_back(x);
		}
		m=0;
		for (int i=1;i<=n;i++) if (!vis[i]) {
			cnt=0;
			dfs(i);
			m+=cnt*(cnt-1)/2;
		}
		printf("%d\n",m);
		exit(0);
	}
};
namespace Star {
	bool check() {
		for (int i=1;i<n;i++)
			if (e[i].x!=1&&e[i].y!=1) return 0;
		return 1;
	}
	int cnt;
	bool vis[2010];
	vector<int> g[2010];
	void dfs(int u) {
		if (vis[u]) return;
		vis[u]=1; cnt++;
		for (int i=0;i<g[u].size();i++) dfs(g[u][i]);
	}
	void solve() {
		int x,y;
		for (int i=1;i<=m;i++) {
			read(x); read(y);
			g[x].push_back(y); g[y].push_back(x);
		}
		m=0;
		cnt=0;
		dfs(1);
		m+=cnt*(cnt-1)/2;
		for (int i=1;i<=n;i++) if (!vis[i]) {
			for (int j=0;j<g[i].size();j++)
				if (g[i][j]>i) m++;
		}
		printf("%d\n",m);
		exit(0);
	}
};
namespace AC {
	int top[2010][2010];
	vector<int> g[2010];
	int fa[2010][2010],ans;
	bool G[2010][2010];
	void dfs1(int u,int p,int S) {
		fa[S][u]=p;
		for (int i=0,v;i<g[u].size();i++) {
			v=g[u][i];
			if (v!=p) dfs1(v,u,S);
		}
	}
	void dfs2(int u,int lst,int S) {
		if (G[lst][u]) ans++,lst=u;
		for (int i=0,v;i<g[u].size();i++) {
			v=g[u][i];
			if (v==fa[S][u]) continue;
			dfs2(v,lst,S);
		}
	}
	queue<int> q;
	void add(int a,int b) {
		if (top[a][b]==b) return;
		if (top[a][b]) { add(top[a][b],b); return; }
		if (top[b][a]) { add(top[b][a],a); return; }
		G[a][b]=G[b][a]=1;
		top[a][b]=b,top[b][a]=a;
		vector<pair<int,int> > h; h.clear();
		q.push(b);
		while (!q.empty()) {
			int u=q.front(); q.pop();
			for (int i=0,v;i<g[u].size();i++) {
				v=g[u][i];
				if (v==fa[a][u]) continue;
				if (top[a][v]) {
					G[top[a][v]][a]=G[a][top[a][v]]=0;
					h.push_back(make_pair(top[a][v],b));
				} else top[a][v]=b,q.push(v);
			}
		}
		swap(a,b);
		q.push(b);
		while (!q.empty()) {
			int u=q.front(); q.pop();
			for (int i=0,v;i<g[u].size();i++) {
				v=g[u][i];
				if (v==fa[a][u]) continue;
				if (top[a][v]) {
					G[top[a][v]][a]=G[a][top[a][v]]=0;
					h.push_back(make_pair(top[a][v],b));
				} else top[a][v]=b,q.push(v);
			}
		}
		for (int i=0;i<h.size();i++) add(h[i].first,h[i].second);
	}
	void solve() {
		//printf("OK\n");
		int x,y;
		for (int i=1;i<n;i++) {
			x=e[i].x,y=e[i].y;
			g[x].push_back(y);
			g[y].push_back(x);
		}
		for (int i=1;i<=n;i++) dfs1(i,0,i);
		for (int i=1;i<=m;i++) {
			read(x); read(y);
			add(x,y);
		}
		for (int i=1;i<=n;i++)
			dfs2(i,i,i);
		printf("%d\n",ans/2);
	}
};
int main() {
	read(n); read(m);
	if (n<=300&&m<=2000) BF::solve();
	for (int i=1;i<n;i++) read(e[i].x),read(e[i].y);
	if (Lian::check()) Lian::solve();
	if (Star::check()) Star::solve();
	AC::solve();
	return 0;
}
/*
  0. Enough array size? Enough array size? Enough array size? Interger overflow?
  
  1. Think TWICE, Code ONCE!
  Are there any counterexamples to your algo?
    
  2. Be careful about the BOUNDARIES!
  N=1? P=1? Something about 0?
    
  3. Do not make STUPID MISTAKES!
  Time complexity? Memory usage? Precision error?
*/

Measured memory_bytes: 36096