#include <bits/stdc++.h>
using namespace std;
const int Nmax = 500005;
class SegmentTree {
 public:
  SegmentTree(const int N)
      : size(N),
        tree(vector<int>(4 * N + 5, 0)),
        add(vector<int>(4 * N + 5, 0)) {}
  void update(int left, int right, int add) {
    if (left > right) return;
    tree_update(1, 1, size, left, right, add);
  }
  int query() const { return tree[1]; }

 private:
  int size;
  vector<int> tree, add;
  void tree_update(int node, int left, int right, int lq, int rq, int val) {
    if (lq <= left && right <= rq) {
      tree[node] += val;
      add[node] += val;
    } else {
      int mid = (left + right) / 2;
      if (lq <= mid) tree_update(2 * node, left, mid, lq, rq, val);
      if (rq > mid) tree_update(2 * node + 1, mid + 1, right, lq, rq, val);
      tree[node] = min(tree[2 * node], tree[2 * node + 1]) + add[node];
    }
  }
};
vector<int> G[Nmax];
int values[Nmax], heights[Nmax];
int father[Nmax];
void getFather(const int node, const int cfather) {
  father[node] = cfather;
  for (int p : G[node])
    if (p != cfather) getFather(p, node);
}
void getVals(int node, int value, vector<int>& vals) {
  vals.push_back(value);
  for (int p : G[node])
    if (p != father[node]) getVals(p, min(value, values[p]), vals);
}
void updateTree(int node, int oldval, int newval, SegmentTree& A, int K) {
  int pos = upper_bound(heights + 1, heights + K + 1, oldval) - heights - 1;
  A.update(1, pos, -1);
  pos = upper_bound(heights + 1, heights + K + 1, newval) - heights - 1;
  A.update(1, pos, 1);
  for (int p : G[node])
    if (p != father[node])
      updateTree(p, min(oldval, values[p]), min(newval, values[p]), A, K);
}
void resetTree(int node, int oldval, int newval, SegmentTree& A, int K) {
  int pos = upper_bound(heights + 1, heights + K + 1, oldval) - heights - 1;
  A.update(1, pos, 1);
  pos = upper_bound(heights + 1, heights + K + 1, newval) - heights - 1;
  A.update(1, pos, -1);
  for (int p : G[node])
    if (p != father[node])
      resetTree(p, min(oldval, values[p]), min(newval, values[p]), A, K);
}
int main() {
  ios::sync_with_stdio(false);
  int N, K;
  cin >> N;
  for (int i = 1; i <= N; ++i) cin >> values[i];
  for (int i = 1; i < N; ++i) {
    int x, y;
    cin >> x >> y;
    G[x].push_back(y);
    G[y].push_back(x);
  }
  getFather(1, -1);
  cin >> K;
  for (int i = 1; i <= K; ++i) cin >> heights[i];
  sort(heights + 1, heights + K + 1);
  priority_queue<pair<int, int>> Q;
  Q.push({values[1], 1});
  vector<pair<int, int>> roots;
  while (K > 0 && !Q.empty()) {
    int node = Q.top().second, eff = Q.top().first;
    Q.pop();
    if (eff < heights[K]) {
      roots.push_back({eff, node});
      continue;
    }
    --K;
    for (int p : G[node])
      if (p != father[node]) Q.push({min(eff, values[p]), p});
  }
  if (K == 0) {
    cout << "0\n";
    return 0;
  }
  SegmentTree A(K);
  for (int i = 1; i <= K; ++i) A.update(i, i, -(K - i + 1));
  for (auto& p : roots) {
    vector<int> vals;
    getVals(p.second, p.first, vals);
    for (int val : vals) {
      int pos = upper_bound(heights + 1, heights + K + 1, val) - heights - 1;
      A.update(1, pos, 1);
    }
  }
  for (auto& p : roots) {
    updateTree(p.second, p.first, heights[K], A, K);
    if (A.query() >= 0) {
      cout << heights[K] - p.first << '\n';
      return 0;
    }
    resetTree(p.second, p.first, heights[K], A, K);
  }
  cout << "-1\n";
  return 0;
}
