#include <bits/stdc++.h>
using namespace std;
template <typename Fn>
class segment_tree {
int n;
vector<int> seg;
Fn merge;
int idt;
public:
segment_tree(int n, const Fn &merge, int idt) : merge(merge), idt(idt), n(n), seg(2 * n, idt) {}
void set(int i, int x) {
for (seg[i += n] = x, i >>= 1; i > 0; i >>= 1) {
seg[i] = merge(seg[2 * i], seg[2 * i + 1]);
}
}
int query(int l, int r) {
int ans = idt;
for (l += n, r += n + 1; l < r; l >>= 1, r >>= 1) {
if (l & 1) ans = merge(ans, seg[l++]);
if (r & 1) ans = merge(ans, seg[--r]);
}
return ans;
}
};
const int inf = 1e9;
struct query {
int l, r, i;
};
struct node {
int mn, cnt;
node(int mn, int cnt) : mn(mn), cnt(cnt) {}
node() : mn(inf), cnt(0) {}
node operator+(const node &r) {
if (mn < r.mn) { return *this; }
if (r.mn < mn) { return r; }
return {mn, cnt + r.cnt};
}
};
class lazy_segment_tree {
int n;
vector<node> seg;
vector<int> lazy;
void push(int v) {
seg[v].mn += lazy[v];
lazy[2 * v] += lazy[v];
lazy[2 * v + 1] += lazy[v];
lazy[v] = 0;
}
void pull(int v) { seg[v] = seg[2 * v] + seg[2 * v + 1]; }
void add(int v, int tl, int tr, int l, int r, int del) {
push(v);
if (tr < l || r < tl) { return; }
if (l <= tl && tr <= r) {
lazy[v] += del;
push(v);
return;
}
int tm = (tl + tr) / 2;
add(2 * v, tl, tm, l, r, del);
add(2 * v + 1, tm + 1, tr, l, r, del);
pull(v);
}
node query(int v, int tl, int tr, int l, int r) {
push(v);
if (tr < l || r < tl) { return node{}; }
if (l <= tl && tr <= r) { return seg[v]; }
int tm = (tl + tr) / 2;
return query(2 * v, tl, tm, l, r) + query(2 * v + 1, tm + 1, tr, l, r);
}
void build(int v, int tl, int tr) {
if (tl == tr) {
seg[v] = node{0, 1};
return;
}
int tm = (tl + tr) / 2;
build(2 * v, tl, tm);
build(2 * v + 1, tm + 1, tr);
pull(v);
}
public:
lazy_segment_tree(int n) : n(n), seg(4 * n), lazy(8 * n) { build(1, 0, n - 1); }
void add(int l, int r, int del) { add(1, 0, n - 1, l, r, del); }
node query(int l, int r) { return query(1, 0, n - 1, l, r); }
};
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int n, m, q;
cin >> n >> m >> q;
vector<vector<int>> adj(n + 1);
for (int i = 0, u, v; i < n - 1; ++i) {
cin >> u >> v;
adj[u].push_back(v), adj[v].push_back(u);
}
vector<int> c(m);
for (int &i : c) {
cin >> i;
}
vector<int> sz(n + 1);
auto dfs_sz = [&](auto &&self, int u, int p) -> void {
if (adj[u].size() > 1 && adj[u][0] == p) { swap(adj[u][0], adj[u][1]); }
sz[u] = 1;
for (int &i : adj[u]) {
if (i == p) { continue; }
self(self, i, u);
sz[u] += sz[i];
if (sz[i] > sz[adj[u][0]]) { swap(i, adj[u][0]); }
}
};
dfs_sz(dfs_sz, 1, 0);
vector<int> up(n + 1);
auto dfs_hld = [&](auto &&self, int u, int p) -> void {
for (int &i : adj[u]) {
if (i == p) { continue; }
up[i] = i == adj[u][0] ? up[u] : i;
self(self, i, u);
}
};
up[1] = 1;
dfs_hld(dfs_hld, 1, 0);
const int w = 17;
vector<array<int, w>> lift(n + 1);
vector<int> dep(n + 1), tin(n + 1);
int timer = 0;
auto dfs = [&](auto &&self, int u, int p, int d) -> void {
tin[u] = timer++;
dep[u] = d;
for (int &i : adj[u]) {
if (i == p) { continue; }
lift[i][0] = u;
self(self, i, u, d + 1);
}
};
lift[1][0] = 1;
dfs(dfs, 1, 0, 0);
for (int bt = 1; bt < w; ++bt) {
for (int i = 1; i <= n; ++i) {
lift[i][bt] = lift[lift[i][bt - 1]][bt - 1];
}
}
auto lca = [&](int u, int v) {
if (u == 0) { return v; }
if (v == 0) { return u; }
if (dep[u] < dep[v]) { // u is deeper
swap(u, v);
}
int k = dep[u] - dep[v];
for (int bt = 0; bt < w; ++bt) {
if (k & 1 << bt) { u = lift[u][bt]; }
}
if (u == v) { return u; }
for (int bt = w - 1; bt >= 0; --bt) {
if (lift[u][bt] != lift[v][bt]) {
u = lift[u][bt], v = lift[v][bt];
}
}
return lift[u][0];
};
segment_tree st_lca(m, lca, 0);
for (int i = 0; i < m; ++i) {
st_lca.set(i, c[i]);
}
vector<query> queries(q);
for (int i = 0, l, r; i < q; ++i) {
cin >> l >> r;
queries[i] = {l - 1, r, i};
}
auto get_chains_hld = [&](int u, int v) {
vector<pair<int, int>> ans;
while (u != v) {
if (dep[u] < dep[v]) { swap(u, v); }
if (up[u] == up[v]) {
ans.push_back({tin[v], tin[u]});
return ans;
}
ans.push_back({tin[up[u]], tin[u]});
u = lift[up[u]][0];
}
ans.push_back({tin[u], tin[u]});
return ans;
};
lazy_segment_tree st(n);
auto apply_node = [&](int u, int del) {
auto chains = get_chains_hld(1, u);
for (auto &[l, r] : chains) {
st.add(l, r, del);
}
};
int L = 0, R = 0; // [L, R)
auto add_front = [&]() {
apply_node(c[R], 1);
R++;
};
auto rem_front = [&]() {
R--;
apply_node(c[R], -1);
};
auto add_back = [&]() {
L--;
apply_node(c[L], 1);
};
auto rem_back = [&]() {
apply_node(c[L], -1);
L++;
};
vector<int> ans(q);
for (auto &[l, r, i] : queries) {
// L, R is where we are
// l, r is where we need to be
while (R < r) add_front();
while (R > r) rem_front();
while (L > l) add_back();
while (L < l) rem_back();
int lc = st_lca.query(l, r - 1);
bool is_root = lc == 1;
if (!is_root) { lc = lift[lc][0]; }
if (!is_root) { apply_node(lc, -(r - l)); }
node qval = st.query(0, n - 1);
int zeroes = qval.mn == 0 ? qval.cnt : 0;
if (!is_root) { apply_node(lc, r - l); }
ans[i] = n - zeroes;
}
for (int &i : ans) {
cout << i << '\n';
}
}