#include <bits/stdc++.h>
using namespace std;
namespace tree {
struct Edge {};
int n;
vector<Edge> edges;
vector<vector<pair<int, int>>> adj;
void makeTree(int _n) {
  n = _n;
  adj = vector<vector<pair<int, int>>>(n);
  edges.clear();
}
template <typename... T>
int addEdge(int from, int to, const T&... e) {
  int id = edges.size();
  adj[from].emplace_back(to, id);
  adj[to].emplace_back(from, id);
  edges.push_back({e...});
  return id;
}
vector<int> depth, pv, pe, pre, endpre, preseq, siz;
int logn;
vector<vector<int>> anc;
struct Jump {
  int sum;
  void init(int v) {
    Edge& e = edges[pe[v]];
    sum = 1;
  }
  void combine(const Jump& x, const Jump& a) { sum = x.sum + a.sum; }
};
vector<vector<Jump>> jump;
void dfs(int x, int p = -1) {
  siz[x] = 1;
  pre[x] = preseq.size();
  preseq.push_back(x);
  for (auto& e : adj[x]) {
    int y = e.first, eid = e.second;
    if (y == p) continue;
    depth[y] = depth[x] + 1;
    pv[y] = x;
    pe[y] = eid;
    dfs(y, x);
    siz[x] += siz[y];
  }
  endpre[x] = (int)preseq.size() - 1;
}
void init(int root = 0) {
  siz = vector<int>(n);
  depth = vector<int>(n);
  pv = vector<int>(n, -1);
  pe = vector<int>(n, -1);
  pre = vector<int>(n, -1);
  endpre = vector<int>(n, -1);
  preseq.clear();
  dfs(root);
  logn = 31 - __builtin_clz(n);
  anc = vector<vector<int>>(n, vector<int>(logn + 1));
  for (int i = 0; i < n; ++i) anc[i][0] = pv[i];
  for (int p = 1; p <= logn; ++p)
    for (int i = 0; i < n; ++i)
      anc[i][p] = anc[i][p - 1] == -1 ? -1 : anc[anc[i][p - 1]][p - 1];
}
bool isAnc(int a, int b) { return pre[a] <= pre[b] && endpre[a] >= endpre[b]; }
int getChildTowards(int a, int sub) {
  int dh = depth[sub] - depth[a] - 1;
  for (int p = logn; p >= 0; --p)
    if (dh & (1 << p)) sub = anc[sub][p];
  return sub;
}
int getAnc(int a, int up) {
  assert(0 <= up && up <= depth[a]);
  for (int p = logn; p >= 0; --p)
    if (up & (1 << p)) a = anc[a][p];
  return a;
}
int getLca(int a, int b) {
  if (isAnc(a, b)) return a;
  if (isAnc(b, a)) return b;
  for (int p = logn; p >= 0; --p)
    if (anc[a][p] != -1 && !isAnc(anc[a][p], b)) a = anc[a][p];
  a = anc[a][0];
  return a;
}
int getDist(int a, int b) {
  int c = getLca(a, b);
  return depth[a] + depth[b] - 2 * depth[c];
}
void jumpUp(int a, int ancestor, function<void(Jump&)> f) {
  assert(isAnc(ancestor, a));
  int up = depth[a] - depth[ancestor];
  for (int p = logn; p >= 0; --p)
    if (up & (1 << p)) {
      f(jump[a][p]);
      a = anc[a][p];
    }
}
vector<int> chainRoot, chainBottom;
void dfsSiz(int x, int p = -1) {
  for (auto it = adj[x].begin(); it != adj[x].end(); ++it)
    if (it->first == p) {
      adj[x].erase(it);
      break;
    }
  siz[x] = 1;
  for (auto& e : adj[x]) {
    int y = e.first;
    dfsSiz(y, x);
    siz[x] += siz[y];
    if (siz[y] > siz[adj[x][0].first]) swap(e, adj[x][0]);
  }
}
void dfsHld(int x, int hldroot) {
  chainRoot[x] = hldroot;
  chainBottom[hldroot] = x;
  for (auto& e : adj[x]) {
    int y = e.first;
    dfsHld(y, y == adj[x][0].first ? hldroot : y);
  }
}
struct Chain {
  vector<int> vs;
  void init(int bot, int top) {
    vs.clear();
    for (int x = bot; x != pv[top]; x = pv[x]) vs.push_back(x);
  }
};
vector<Chain> chains;
void moveUp(int x, int y, function<void(Chain&, int, int)> f) {
  for (;;) {
    int z = chainRoot[x];
    bool isLastChain = z == chainRoot[y];
    f(chains[chainRoot[x]], x, isLastChain ? y : z);
    if (isLastChain) break;
    x = pv[z];
  }
}
void initHld(int root = 0) {
  siz = vector<int>(n);
  dfsSiz(root);
  init(root);
  chainRoot = vector<int>(n);
  chainBottom = vector<int>(n);
  dfsHld(root, root);
  chains = vector<Chain>(n);
  for (int i = 0; i < n; ++i) {
    if (chainRoot[i] != i) continue;
    chains[i].init(chainBottom[i], i);
  }
}
};  // namespace tree
using namespace tree;
struct DisjointSet {
  vector<int> par;
  DisjointSet(int n) : par(n) { iota(par.begin(), par.end(), 0); }
  int get(int a) {
    if (par[a] == a) return a;
    return par[a] = get(par[a]);
  }
  bool join(int a, int b) {
    int pa = get(a), pb = get(b);
    if (pa == pb) return false;
    par[pa] = pb;
    return true;
  }
};
int main() {
  int n, K, r;
  scanf("%d%d%d", &n, &K, &r);
  int N = n + n - 1;
  makeTree(N);
  for (int i = 0; i < n - 1; ++i) {
    int a, b;
    scanf("%d%d", &a, &b);
    --a;
    --b;
    addEdge(a, n + i);
    addEdge(n + i, b);
  }
  init();
  queue<int> Q;
  vector<int> sp(N, -1), label(N, -1);
  for (int i = 0; i < r; ++i) {
    int x;
    scanf("%d", &x);
    --x;
    Q.push(x);
    sp[x] = 0;
    label[x] = i;
  }
  while (!Q.empty()) {
    auto x = Q.front();
    Q.pop();
    for (auto& e : adj[x]) {
      int y = e.first;
      if (sp[y] != -1) continue;
      sp[y] = sp[x] + 1;
      label[y] = label[x];
      Q.push(y);
    }
  }
  DisjointSet dsu(r);
  for (int x = 0; x < N; ++x) {
    for (auto& e : adj[x]) {
      int y = e.first;
      if (sp[x] + sp[y] + 1 <= 2 * K) dsu.join(label[x], label[y]);
    }
  }
  int q;
  scanf("%d", &q);
  while (q--) {
    int a, b;
    scanf("%d%d", &a, &b);
    --a;
    --b;
    int lca = getLca(a, b);
    int dist = depth[a] + depth[b] - 2 * depth[lca];
    if (dist <= 2 * K)
      printf("YES\n");
    else {
      if (depth[a] < depth[b]) swap(a, b);
      int aa = getAnc(a, K);
      int bb;
      if (depth[b] - depth[lca] >= K)
        bb = getAnc(b, K);
      else
        bb = getAnc(aa,
                    (depth[aa] - depth[lca]) - (K - (depth[b] - depth[lca])));
      if (sp[aa] <= K && sp[bb] <= K &&
          dsu.get(label[aa]) == dsu.get(label[bb]))
        printf("YES\n");
      else
        printf("NO\n");
    }
  }
}
