#include <bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN = 1e5 + 10;
const int MAXK = 20;
array<vector<int>, MAXN> grafo;
array<vector<pair<int, int>>, MAXN> totPath;
array<int, MAXN> bit, tin, tout, prof, sub, lcaFreq, endPathFreq, remov, centroidPathQueries;
array<array<int, MAXK>, MAXN> bin;
int resp = 0;

void update(int id, int val)
{
	while (id < MAXN)
	{
		bit[id] += val;
		id += id&-id;
	}
}

int query(int id)
{
	int resp = 0;
	while (id > 0)
	{
		resp += bit[id];
		id -= id&-id;
	}
	return resp;
}

int lca(int a, int b)
{
	if (prof[a] < prof[b]) swap(a, b);
	int D = prof[a] - prof[b];
	for (int k = 0; k < MAXK; k++) 
		if (D & (1 << k))
			a = bin[a][k];
	if (a == b) return a;
	for (int k = MAXK-1; k >= 0; k--)
		if (bin[a][k] != bin[b][k])
			a = bin[a][k], b = bin[b][k];
	return bin[a][0];
}

void dfsInit(int v, int p, int &temp)
{
	sub[v] = 1; bin[v][0] = p; prof[v] = prof[p]+1;
	for (int k = 1; k < MAXK; k++) bin[v][k] = bin[bin[v][k-1]][k-1];
	tin[v] = ++temp; lcaFreq[v] = 0; endPathFreq[v] = 0; centroidPathQueries[v] = 0;

	for (auto viz : grafo[v])
	{
		if (viz == p || remov[viz]) continue;
		dfsInit(viz, v, temp);
		sub[v] += sub[viz];
	}

	tout[v] = temp;
}

int findCentroid(int v, int p, int N)
{
	for (auto viz : grafo[v])
	{
		if (viz == p || remov[viz]) continue;
		if (sub[viz] > N/2) return findCentroid(viz, v, N);
	}
	return v;
}

void dfsPreCalc(int v, int p)
{
	for (auto viz : grafo[v])
	{
		if (viz == p || remov[viz]) continue;
		dfsPreCalc(viz, v);
		lcaFreq[v] += lcaFreq[viz];
	}
}

void dfsCalc(int v, int p, int goodLcas, int goodEnds)
{
	int sum = 0; goodEnds += endPathFreq[v];
	for (auto viz : grafo[v]) if (viz != p && !remov[viz]) sum += lcaFreq[viz];

	// cerr << "v: " << v << ", goodLcas: " << goodLcas << ", sum: " << sum << ", goodEnds: " << goodEnds << '\n';
	resp += centroidPathQueries[v] * (goodLcas + sum + goodEnds);

	for (auto viz : grafo[v])
	{
		if (viz == p || remov[viz]) continue;
		dfsCalc(viz, v, goodLcas + sum - lcaFreq[viz], goodEnds);
	}
}

void decomp(int v, int temp)
{
	vector<pair<int, int>> paths = totPath[v]; 
	totPath[v].clear(); 
	if (paths.empty()) return;
	int iniTemp = temp+1;
	dfsInit(v, v, iniTemp);
	int c = findCentroid(v, v, sub[v]);
	prof[c] = 0; iniTemp = temp+1;
	dfsInit(c, c, temp);
	// cerr << "decomp: " << c << '\n';

	vector<pair<int, int>> centroidInters;
	vector<vector<pair<int, int>>> sweep(temp-iniTemp+1); int totRecurse = 0;
	for (auto [x, y] : paths)
	{
		if (tin[x] > tin[y]) swap(x, y);
		int L = lca(x, y);
		if (L == c) 
		{
			centroidInters.emplace_back(x, y);
			if (x != c) 
			{
				sweep[tin[x]-iniTemp].emplace_back(-tin[y], tout[y]);
				// sweep[tin[x]-iniTemp].emplace_back(0, tin[y]);
				sweep[tout[x]-iniTemp].emplace_back(tin[y], tout[y]);
			}
			centroidPathQueries[x]++; centroidPathQueries[y]++;
		}
		else 
		{
			lcaFreq[L]++;
			if (L == x) endPathFreq[y]++;

			for (int k = MAXK-1; k >= 0; k--) if (bin[L][k] != c) L = bin[L][k];
			totPath[L].emplace_back(x, y);
			++totRecurse;
		}
	}


	// bit.fill(0);
	for (auto &line : sweep)
	{
		sort(line.begin(), line.end(), [](pair<int,int> a, pair<int,int> b) {
			if ((a.first < 0) != (b.first < 0)) return a.first < b.first;
			if (a.first < 0) return a.first > b.first;
			return a.first > b.first;
		});
		for (auto [x, y] : line)
		{
			if (x < 0) {update(-x, +1); resp -= query(y)-query(-x-1);}
			else resp += query(y)-query(x-1);
			// cerr << "x: " << x << ", y: " << y << '\n';
			// if (x < 0) cerr << "||" << query(y)-query(-x) << '\n';
			// else if (x > 0) cerr << "||" << query(y)-query(x) << '\n';
		}
	}
	// cerr << "respCenters: " << resp << '\n'; 

	for (auto [x, y] : centroidInters) if (x != c) update(tin[x], +1);
	vector<pair<int,int>> downs;
	for(auto p : centroidInters) if(p.first == c) downs.push_back(p);
	sort(downs.begin(), downs.end(), [&](pair<int,int> a, pair<int,int> b){ return prof[a.second] > prof[b.second]; });
	for(auto p : downs) { int y = p.second; resp += query(tout[y]) - query(tin[y]-1); update(tin[y], +1); }

	for (auto [x, y] : centroidInters)
	{
		if (x != c) update(tin[x], -1);
		update(tin[y], -1);
	}

	dfsPreCalc(c, c);
	for (auto viz : grafo[c]) if (!remov[viz]) dfsCalc(viz, c, 0, 0);
	for (auto [x, y] : centroidInters)
	{
		int aux = lcaFreq[c];
		// cerr << "=> x: " << x << ", y: " << y << '\n';
		for (int k = MAXK-1; k >= 0; k--)
		{
			if (bin[x][k] != c) x = bin[x][k];
			if (bin[y][k] != c) y = bin[y][k];
		}
		if (x != c) aux -= lcaFreq[x];
		if (y != c) aux -= lcaFreq[y];
		// cerr << "aux: " << aux << '\n';
		resp += aux;
	}

	int aux = 0;
	for (auto viz : grafo[c]) if (!remov[viz]) aux += (int)totPath[viz].size() * (totRecurse - (int)totPath[viz].size());
	resp += aux/2LL;  

	remov[c] = 1;

	// cerr << "resp: " << resp << '\n';
	for (auto viz : grafo[c]) if (!remov[viz]) decomp(viz, tin[viz]-1);
}

int32_t main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	int N, Q, T; cin >> N >> Q >> T;
	for (int i = 1; i < N; i++)
	{
		int X, Y; cin >> X >> Y;
		grafo[X].push_back(Y);
		grafo[Y].push_back(X);
	}

	for (int i = 0; i < Q; i++)
	{
		int x, y; cin >> x >> y;
		if (x == y) resp += (Q-i+(int)totPath[1].size()-1);
		else totPath[1].emplace_back(x, y);
	}

	decomp(1, 0);

	if (T == 0) cout << (resp == (Q*(Q-1))/2LL ? 1 : 0) << '\n';
	else cout << resp << '\n';
}