//by yjz
#include<bits/stdc++.h>
using namespace std;
#define FF first
#define SS second
#define PB push_back
#define MP make_pair
#ifndef LOCAL
#define cerr if(0)cout
#endif
typedef long long ll;
const int mod = 1e9+7;
//My i/o stream
struct fastio
{
	char s[100000];
	int it, len;
	fastio() {it=len=0;}
	inline char get()
	{
		if (it<len) return s[it++]; it=0;
		len=fread(s, 1, 100000, stdin);
		if (len==0) return EOF; else return s[it++];
	}
	bool notend()
	{
		char c=get();
		while (c==' '||c=='\n') c=get();
		if (it>0) it--;
		return c!=EOF;
	}
}_buff;
#define geti(x) x=getnum()
#define getii(x,y) geti(x),geti(y)
#define getiii(x,y,z) getii(x,y),geti(z)
#define puti(x) putnum(x),putchar(' ')
#define putii(x,y) puti(x),puti(y)
#define putiii(x,y,z) putii(x,y),puti(z)
#define putsi(x) putnum(x),putchar('\n')
#define putsii(x,y) puti(x),putsi(y)
#define putsiii(x,y,z) putii(x,y),putsi(z)
inline ll getnum()
{
	ll r=0; bool ng=0; char c; c=_buff.get();
	while (c!='-'&&(c<'0'||c>'9')) c=_buff.get();
	if (c=='-') ng=1, c=_buff.get();
	while (c>='0'&&c<='9') r=r*10+c-'0', c=_buff.get();
	return ng?-r:r;
}
template <class T> inline void putnum(T x)
{
	if (x<0) putchar('-'), x=-x;
	register short a[20]={}, sz=0;
	while (x) a[sz++]=x%10, x/=10;
	if(sz==0) putchar('0');
	for (int i=sz-1; i>=0; i--) putchar('0'+a[i]);
}
inline char getreal() {char c=_buff.get(); while (c<=32) c=_buff.get(); return c;}
ll qpow(ll x, ll k) {return k==0? 1: 1ll*qpow(1ll*x*x%mod,k>>1)*(k&1?x:1)%mod;}
int n, m;
const int maxn = 2011;
bitset<2011> adj[maxn];
int lca[maxn][maxn], dfn[maxn], dfnr[maxn], dtot, fa[maxn];
bitset<2011> tab[maxn];
vector<int> con[maxn];
void pdfs(int x)
{
	dfn[x] = ++dtot;
	for (auto u : con[x])
	{
		if (fa[x]==u) continue;
		fa[u] = x;
		pdfs(u);
	}
	dfnr[x] = dtot;
}
vector<int> v;
void dfs(int x, int pre)
{
	v.PB(x);
	for (auto u : con[x])
	{
		if (u==pre) continue;
		dfs(u, x);
	}
}
int ans;
int getson(int x, int y)
{
	for (auto u : con[x])
	{
		if (u!=fa[x]&&dfn[u]<=dfn[y]&&dfn[y]<=dfnr[u]) return u;
	}
	assert(false);
}
vector<pair<int,int> > q;
void add_edge(int x, int y)
{
	ans++;
	if (dfn[x]>dfn[y]) swap(x, y);
	bitset<2011> b;
	if (dfn[x]<=dfn[y]&&dfnr[y]<=dfnr[x])
	{
		b = ~tab[getson(x, y)]|tab[y];
	}
	else
	{
		assert(lca[x][y]>0);
		b = tab[x]^tab[y]; b[lca[x][y]] = 1;
	}
//	for (int i=1; i<=n; i++) cerr<<b[i]; cerr<<endl;
	bool f = 0;
	bitset<2011> c;
	c = b&~adj[x]&adj[y]; c[0] = 0;
	for (int t = c._Find_first(); t<=n; t = c._Find_next(t))
	{
		assert(!adj[x][t]);
		adj[x][t] = adj[t][x] = 1;
		q.PB(MP(x, t));
	}
	c = b&~adj[y]&adj[x]; c[0] = 0;
	for (int t = c._Find_first(); t<=n; t = c._Find_next(t))
	{
		assert(!adj[y][t]);
		adj[y][t] = adj[t][y] = 1;
		q.PB(MP(y, t));
	}
}
int main()
{
	getii(n, m);
	for (int i=1; i<=n; i++) adj[i][i] = 1;
	for (int i=1; i<n; i++)
	{
		int x, y;
		getii(x, y);
		con[x].PB(y);
		con[y].PB(x);
	}
	pdfs(1);
	for (int i=1; i<=n; i++)
	{
		vector<vector<int> > V;
		for (auto u : con[i])
		{
			if (u==fa[i]) continue;
			v.clear();
			dfs(u, i);
			V.PB(v);
			for (auto x : v) tab[i][x] = 1;
		}
		for (int j=0; j<V.size(); j++)
		{
			for (int k=j+1; k<V.size(); k++)
			{
				for (auto x : V[j]) for (auto y : V[k])
				{
					lca[x][y] = lca[y][x] = i;
				}
			}
		}
		int x = i;
		while (x)
		{
			tab[i][x] = 1;
			x = fa[x];
		}
	}
	for (int i=1; i<=m; i++)
	{
		int x, y;
		getii(x, y);
		q.PB(MP(x, y));
		adj[x][y] = adj[y][x] = 1;
	}
	for (int i=0; i<q.size(); i++)
	{
		add_edge(q[i].FF, q[i].SS);
	}
	cout<<ans<<endl;
	return 0;
}


Measured memory_bytes: 35816