#include <bits/stdc++.h>
using namespace std;
#ifdef LOCAL
string to_string(string s) { return '"' + s + '"'; }
string to_string(const char* s) { return to_string(string(s)); }
string to_string(bool b) { return to_string(int(b)); }
string to_string(vector<bool>::reference b) { return to_string(int(b)); }
string to_string(char b) { return "'" + string(1, b) + "'"; }
template <typename A, typename B>
string to_string(pair<A, B> p) { return "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; }
template <typename A>
string to_string(A v) {
	string res = "{";
	for (const auto& x : v) res += (res == "{" ? "" : ", ") + to_string(x);
	return res + "}";
}
void debug() { cerr << endl; }
template <typename Head, typename... Tail>
void debug(Head H, Tail... T) {
	cerr << " " << to_string(H);
	debug(T...);
}
#define db(...) cerr << "[" << #__VA_ARGS__ << "]:", debug(__VA_ARGS__)
#else
#define db(...) 42
#endif
typedef long long ll;
typedef long double ld;
int main() {
	int n, K;
	scanf("%d%d", &n, &K);
	vector<vector<int>> E(n);
	for (int i = 1; i < n; ++i) {
		int u, v;
		scanf("%d%d", &u, &v);
		--u;
		--v;
		E[u].push_back(v);
		E[v].push_back(u);
	}
	vector<int> depth(n, -1), par(n, -1);
	depth[0] = 0;
	function<void(int)> dfs = [&](int x) {
		for (int y : E[x]) {
			if (depth[y] != -1) continue;
			depth[y] = depth[x] + 1;
			par[y] = x;
			dfs(y);
		}
	};
	dfs(0);
	vector<int> vs(n);
	iota(vs.begin(), vs.end(), 0);
	sort(vs.begin(), vs.end(), [&](int x, int y) {
		return depth[x] > depth[y];
	});
	auto check = [&](int d) {
		vector<bool> used(n);
		function<void(int, int, int)> flood = [&](int x, int cur, int p) {
			used[x] = true;
			if (!cur) return;
			for (int y : E[x]) {
				if (y == p) continue;
				flood(y, cur - 1, x);
			}
		};
		int need = 0;
		for (int v : vs) {
			if (used[v]) continue;
			++need;
			if (need > K) return false;
			int x = v;
			for (int i = 0; i < d; ++i) {
				if (par[x] == -1) break;
				x = par[x];
			}
			flood(x, d, -1);
			assert(used[v]);
		}
		return true;
	};
	int lo = 1, hi = n - 1;
	while (lo < hi) {
		int d = (lo + hi) >> 1;
		if (check(d)) hi = d;
		else lo = d + 1;
	}
	printf("%d\n", lo);
}

#include <bits/stdc++.h>
#define ll long long
#define sz(x) (int)(x).size()
using namespace std;
//mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
//uniform_int_distribution<int>(1000,10000)(rng)

ll binpow(ll a, ll b)
{
    ll res = 1;
    while (b > 0)
    {
        if (b & 1)
            res = res * a;
        a = a * a;
        b >>= 1;
    }
    return res;
}

ll gcd(ll a,ll b)
{
    if (b==0) return a;
    return gcd(b,a%b);
}

string to_upper(string a)
{
    for (int i=0;i<(int)a.size();++i) if (a[i]>='a' && a[i]<='z') a[i]-='a'-'A';
    return a;
}
 
string to_lower(string a)
{
    for (int i=0;i<(int)a.size();++i) if (a[i]>='A' && a[i]<='Z') a[i]+='a'-'A';
    return a;
}

int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0);
    int n,m,k,ans=0,cur;
    cin>>n>>m;
    int a[m][2],b[n+1];
    for (int i=0;i<m;++i)
        cin>>a[i][0]>>a[i][1];
    cin>>k;
    int c[k][2];
    for (int i=0;i<k;++i)
        cin>>c[i][0]>>c[i][1];
    for (int i=0;i<(1<<k);++i)
    {
        for (int j=1;j<=n;++j)
            b[j]=0;
        for (int j=0;j<k;++j)
        {
            if (i&(1<<j))
                ++b[c[j][0]];
            else
                ++b[c[j][1]];
        }
        cur=0;
        for (int j=0;j<m;++j)
            if (b[a[j][0]]&&b[a[j][1]])
                ++cur;
        ans=max(ans,cur);
    }
    cout<<ans;
    return 0;
}