#include <bits/stdc++.h>
using namespace std;
template <typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << "{";
  for (const T &a : v) out << a << ", ";
  out << "}";
  return out;
}
template <typename S, typename T>
ostream &operator<<(ostream &out, const pair<S, T> &p) {
  out << "(" << p.first << ", " << p.second << ")";
  return out;
}
const int dx[] = {0, 0, -1, 1};
const int dy[] = {-1, 1, 0, 0};
const int MAXN = 500010;
const int INF = 1000000010;
int n, k, m, d;
int tree_val[2 * 512 * 1024];
int tree_mod[2 * 512 * 1024];
int height[MAXN];
int eff[MAXN];
int cur[MAXN];
int parent[MAXN];
vector<int> edges[MAXN];
int miner[MAXN];
vector<int> roots;
vector<int> got;
void set_val(int first, int second) {
  first += d;
  tree_val[first] = second;
  first /= 2;
  while (first) {
    tree_val[first] = min(tree_val[2 * first], tree_val[2 * first + 1]);
    first /= 2;
  }
}
void tree_add_val(int u, int lo, int hi, int first, int second, int c) {
  if (second < lo || hi < first) return;
  if (first <= lo && hi <= second) {
    tree_val[u] += c;
    tree_mod[u] += c;
    return;
  }
  tree_add_val(2 * u, lo, (lo + hi) / 2, first, second, c);
  tree_add_val(2 * u + 1, (lo + hi) / 2 + 1, hi, first, second, c);
  tree_val[u] = min(tree_val[2 * u], tree_val[2 * u + 1]) + tree_mod[u];
}
void add_val(int first, int second, int c) {
  tree_add_val(1, 0, d - 1, first, second - 1, c);
}
int get_min() { return tree_val[1]; }
void dfs_eff(int u) {
  got.push_back(eff[u]);
  for (int v : edges[u])
    if (parent[u] != v) {
      parent[v] = u;
      eff[v] = min(eff[u], height[v]);
      dfs_eff(v);
    }
}
int get_satisifed(int h) {
  return (int)(upper_bound(miner, miner + m, h) - miner);
}
void perform(int u) {
  int g = get_satisifed(eff[u]);
  add_val(0, g, -1);
  g = get_satisifed(cur[u]);
  add_val(0, g, 1);
  for (int v : edges[u])
    if (parent[u] != v) {
      parent[v] = u;
      cur[v] = min(cur[u], height[v]);
      perform(v);
    }
}
void unwind(int u) {
  int g = get_satisifed(eff[u]);
  add_val(0, g, 1);
  g = get_satisifed(cur[u]);
  add_val(0, g, -1);
  for (int v : edges[u])
    if (parent[u] != v) {
      parent[v] = u;
      unwind(v);
    }
}
int solve() {
  priority_queue<pair<int, int> > Q;
  eff[1] = height[1];
  Q.push(pair<int, int>(eff[1], 1));
  m = k;
  while (m) {
    int u = Q.top().second;
    if (eff[u] < miner[m - 1]) {
      while (!Q.empty()) {
        u = Q.top().second;
        Q.pop();
        roots.push_back(u);
        dfs_eff(u);
      }
      sort(got.begin(), got.end());
      d = 1;
      while (d < m) d *= 2;
      int skip = 0;
      for (int i = (0); i < (m); ++i) {
        while (skip < ((int)(got).size()) && got[skip] < miner[i]) {
          ++skip;
        }
        set_val(i, ((int)(got).size()) - skip - (m - i));
      }
      for (int i = (0); i < (((int)(roots).size())); ++i) {
        u = roots[i];
        cur[u] = miner[m - 1];
        perform(u);
        if (get_min() >= 0) return miner[m - 1] - height[u];
        unwind(u);
      }
      return -1;
    }
    Q.pop();
    --m;
    for (int v : edges[u])
      if (parent[u] != v) {
        parent[v] = u;
        eff[v] = min(eff[u], height[v]);
        Q.push(pair<int, int>(eff[v], v));
      }
  }
  return 0;
}
int main() {
  scanf("%d", &n);
  for (int i = (1); i < (n + 1); ++i) scanf("%d", &height[i]);
  for (int i = (1); i < (n); ++i) {
    int a, b;
    scanf("%d %d", &a, &b);
    edges[a].push_back(b);
    edges[b].push_back(a);
  }
  scanf("%d", &k);
  for (int i = (0); i < (k); ++i) scanf("%d", &miner[i]);
  sort(miner, miner + k);
  printf("%d\n", solve());
  return 0;
}
