#include <bits/stdc++.h>
#define endl '\n'

//#pragma GCC optimize ("O3")
//#pragma GCC target ("sse4")

#define SZ(x) ((int)x.size())
#define ALL(V) V.begin(), V.end()
#define L_B lower_bound
#define U_B upper_bound
#define pb push_back

using namespace std;
template<class T, class T2> inline int chkmax(T &x, const T2 &y) { return x < y ? x = y, 1 : 0; }
template<class T, class T2> inline int chkmin(T &x, const T2 &y) { return x > y ? x = y, 1 : 0; }
const int MAXN = (1 << 20);

int tr[MAXN];

void add(int p, int v) { for(; p < MAXN; p += (p & -p)) tr[p] += v; }

int query(int p)
{
	int ans = 0;
	for(; p >= 1; p -= (p & -p)) ans += tr[p];
	return ans;
}

int n, m;
vector<int> adj[MAXN];
int st[MAXN], en[MAXN], par[MAXN][20], dfs_time;

int A[MAXN], B[MAXN];

void read()
{
	cin >> n >> m;
	m -= n - 1;
	for(int i = 0; i < n - 1; i++)
	{
		int u, v;
		cin >> u >> v;
		adj[u].pb(v);
		adj[v].pb(u);
	}

	for(int i = 0; i < m; i++)
		cin >> A[i] >> B[i];
}

void pre_dfs(int u, int pr)
{
	st[u] = ++dfs_time;
	par[u][0] = pr;
	for(int i = 1; i < 20; i++)
		par[u][i] = par[par[u][i - 1]][i - 1];

	for(int v: adj[u])
		if(v != pr)
			pre_dfs(v, u);

	en[u] = dfs_time;
}

bool upper(int u, int v) { return st[u] <= st[v] && st[v] <= en[u]; }

int lca(int u, int v) 
{
	if(upper(u, v)) return u;
	if(upper(v, u)) return v;

	for(int i = 19; i >= 0; i--)
		if(!upper(par[u][i], v))
			u = par[u][i];

	return par[u][0];
}

int get_u(int u, int anc)
{
	if(u == anc) return -1;
	for(int i = 19; i >= 0; i--)
		if(!upper(par[u][i], anc))
			u = par[u][i];

	return u;
}

int64_t answer;
vector<int> li[MAXN];

int64_t C2(int x) { return x * 1ll * (x - 1) / 2ll; }

void dfs(int u, int pr)
{
	map<int, int> M1;
	map<pair<int, int>, int> M2;
	for(int i: li[u])
	{
		int x = get_u(A[i], u), y = get_u(B[i], u);
		
		if(x > y) swap(x, y);
		if(x != -1) answer += query(en[x]) - query(st[x] - 1);
		if(y != -1) answer += query(en[y]) - query(st[y] - 1);
	
		if(x != -1) M1[x]++;
		if(y != -1) M1[y]++;
		if(x != -1 && y != -1) M2[{x, y}]++;
	}

	for(auto it: M1) answer += C2(it.second);
	for(auto it: M2) answer -= C2(it.second);

	for(int i: li[u])
	{
		int x = A[i], y = B[i];
		add(st[x], 1);
		add(st[y], 1);
	}

	for(int v: adj[u])
		if(v != pr)
			dfs(v, u);

	for(int i: li[u])
	{
		int x = A[i], y = B[i];
		add(st[x], -1);
		add(st[y], -1);
	}
}

void solve()
{
	pre_dfs(1, 1);
	
	for(int i = 0; i < m; i++)
	{
		int l = lca(A[i], B[i]);
		li[l].pb(i);
	}
	
	dfs(1, 1);
	cout << answer << endl;
}

int main()
{
	freopen("exercise.in", "r", stdin);
	freopen("exercise.out", "w", stdout);
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	read();
	solve();
	return 0;
}

