#pragma comment(linker, "/STACK:1024000000,1024000000") 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;

vector<int> E[100010];
int dp[20][100010];
int deep[100010];
int n, m;

void dfs(int u, int father, int depth)
{
	dp[0][u] = father;
	deep[u] = depth;
	for (int i = 0; i < E[u].size(); i++) {
		int v = E[u][i];
		if (v == father) continue;
		dfs(v, u, depth + 1);
	}
}

int get(int u, int v)
{
	if (deep[u] > deep[v]) swap(u, v);
	while (deep[u] < deep[v]) {
		int k = log(deep[v] - deep[u]) / log(2);
		v = dp[k][v];
	}
	while (u != v) {
		int k = 0;
		for (int i = 0; ; i++){
			if (dp[i + 1][u] == dp[i + 1][v]) {
				u = dp[i][u];
				v = dp[i][v];
				break;
			}
		}
	}
	return u;
}

struct node
{
	int u, v, x;
	node(){}
	node(int u, int v, int x) : u(u), v(v), x(x){}
	bool operator < (const node &rhs) const{
		return deep[x] > deep[rhs.x];
	}
};

int vis[100010];

void cover(int u)
{
	vis[u] = 1;
	for (int i = 0; i < E[u].size(); i++) {
		int v = E[u][i];
		if (!vis[v] && deep[v] > deep[u]) {
			cover(v);
		}
	}
}

int main()
{
	ios::sync_with_stdio(false);
	while (cin >> n >> m) {
		for (int i = 0; i <= n; i++) {
			E[i].clear();
		}
		for (int i = 1; i < n; i++) {
			int u, v;
			cin >> u >> v;
			E[u].push_back(v);
			E[v].push_back(u);
		}
		dfs(1, 0, 0);
		for (int i = 1; i < 20; i++) {
			for (int j = 1; j <= n; j++) {
				dp[i][j] = dp[i - 1][dp[i - 1][j]];
			}
		}
		vector<node> Q;
		for (int i = 0; i < m; i++) {
			int u, v;
			cin >> u >> v;
			int x = get(u, v);
			Q.push_back(node(u, v, x));
		}
		sort(Q.begin(), Q.end());
		memset(vis, 0, sizeof(vis));
		int ans = 0;
		for (int i = 0; i < m; i++) {
			int u = Q[i].u, v = Q[i].v, x = Q[i].x;
			if (!vis[u] && !vis[v]) {
				ans++;
				cover(x);
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}
