#include <bits/stdc++.h>
using namespace std;
inline int read() {
  int x = 0, f = 1;
  char c = getchar();
  while (!isdigit(c)) {
    if (c == '-') f = -1;
    c = getchar();
  }
  while (isdigit(c)) {
    x = x * 10 + c - '0';
    c = getchar();
  }
  return x * f;
}
const int MAXN = 5e5 + 10;
int n, fa[MAXN], d[MAXN], w[MAXN], rnk[MAXN];
int mn[MAXN << 2], tag[MAXN << 2];
struct Heap {
  priority_queue<pair<int, int> > q1, q2;
  Heap() {}
  inline void insert(pair<int, int> now) { q1.push(now); }
  inline void remove(pair<int, int> now) { q2.push(now); }
  inline void fix() {
    while (q2.size() && q1.top() == q2.top()) q1.pop(), q2.pop();
  }
  inline void pop() { q1.pop(); }
  inline pair<int, int> top() {
    fix();
    return q1.top();
  }
  inline int size() { return q1.size() - q2.size(); }
} myheap;
vector<int> Candidate;
inline void update(int x) { mn[x] = min(mn[(x << 1)], mn[(x << 1 | 1)]); }
inline void operate(int x, int v) { tag[x] += v, mn[x] += v; }
inline void pushdown(int x) {
  if (tag[x]) {
    int v = tag[x];
    operate((x << 1), v);
    operate((x << 1 | 1), v);
    tag[x] = 0;
  }
}
inline void modify(int x, int l, int r, int ql, int qr, int v) {
  if (ql > qr) return;
  if (l >= ql && r <= qr) return operate(x, v);
  int mid = (l + r) >> 1;
  pushdown(x);
  if (ql <= mid) modify((x << 1), l, mid, ql, qr, v);
  if (qr > mid) modify((x << 1 | 1), mid + 1, r, ql, qr, v);
  update(x);
}
inline int query(int x, int l, int r, int ql, int qr) {
  if (ql > qr) return 0;
  if (l >= ql && r <= qr) return mn[x];
  int mid = (l + r) >> 1, res = 0;
  pushdown(x);
  if (ql <= mid) res = min(res, query((x << 1), l, mid, ql, qr));
  if (qr > mid) res = min(res, query((x << 1 | 1), mid + 1, r, ql, qr));
  return res;
}
inline int find(int x, int l, int r) {
  if (l == r) return l;
  int mid = (l + r) >> 1;
  pushdown(x);
  if (mn[(x << 1 | 1)] < 0)
    return find((x << 1 | 1), mid + 1, r);
  else
    return find((x << 1), l, mid);
}
vector<int> linker[MAXN];
void GetCandidate() {
  Candidate.clear();
  myheap.insert(pair<int, int>(d[1], 1));
  for (int i = n; i >= 1; i--) {
    pair<int, int> now = myheap.top();
    if (now.first < w[i]) {
      Candidate.push_back(now.second);
      myheap.pop();
      for (; myheap.size(); myheap.pop())
        Candidate.push_back(myheap.top().second);
      break;
    }
    myheap.pop();
    for (int cur : linker[now.second])
      if (cur != fa[now.second]) myheap.insert(pair<int, int>(d[cur], cur));
  }
  if (Candidate.empty()) {
    puts("0");
    exit(0);
  }
}
int lim[MAXN];
void dfs(int x, int mn) {
  lim[x] = mn;
  mn = min(mn, rnk[x]);
  modify(1, 1, n, 1, mn, 1);
  for (int cur : linker[x])
    if (cur != fa[x]) dfs(cur, mn);
}
vector<int> tv;
const int INF = 0x3f3f3f3f;
void foo(int x, int mn) {
  mn = min(mn, rnk[x]);
  tv.push_back(mn);
  for (int cur : linker[x])
    if (cur != fa[x]) foo(cur, mn);
}
int ans;
struct tumple {
  int l, r, v;
  tumple() {}
  tumple(int l, int r, int v) : l(l), r(r), v(v) {}
};
vector<tumple> mystack;
inline void refine() {
  for (tumple &cur : mystack) modify(1, 1, n, cur.l, cur.r, -cur.v);
  mystack.clear();
}
int R;
void Solve(int x) {
  int limit = lim[x], now = min(limit, rnk[x]);
  if (query(1, 1, n, 1, now) < 0 || R > lim[x]) return;
  tv.clear(), mystack.clear();
  for (int cur : linker[x])
    if (cur != fa[x]) foo(cur, lim[x]);
  sort(tv.begin(), tv.end());
  int st = upper_bound(tv.begin(), tv.end(), now) - tv.begin();
  modify(1, 1, n, now, R, 1);
  mystack.push_back(tumple(now + 1, R, 1));
  for (int i = st, j; i < tv.size(); i = j + 1) {
    int bar = tv[i];
    for (j = i; j < tv.size() - 1 && tv[j + 1] == bar; j++)
      ;
    modify(1, 1, n, now + 1, min(R, bar), j - i + 1);
    mystack.push_back(tumple(now + 1, min(R, bar), j - i + 1));
  }
  if (mn[1] >= 0) ans = min(ans, w[R] - d[x]);
  refine();
}
void build(int x, int l, int r) {
  if (l == r) {
    mn[x] = -(n - l + 1);
    return;
  }
  int mid = (l + r) >> 1;
  build((x << 1), l, mid);
  build((x << 1 | 1), mid + 1, r);
  mn[x] = -(n - l + 1);
}
void _dfs(int x) {
  for (int cur : linker[x]) {
    if (cur == fa[x]) continue;
    fa[cur] = x;
    _dfs(cur);
  }
}
int main() {
  n = read(), ans = INF;
  for (int i = 1; i <= n; i++) d[i] = read();
  for (int i = 1; i < n; i++) {
    int u = read(), v = read();
    linker[u].push_back(v);
    linker[v].push_back(u);
  }
  _dfs(1);
  int bar = read();
  for (int i = 1; i <= bar; i++) w[i] = read();
  sort(w + 1, w + 1 + n);
  for (int i = 1; i <= n; i++)
    rnk[i] = upper_bound(w + 1, w + 1 + n, d[i]) - w - 1;
  build(1, 1, n), dfs(1, INF), GetCandidate();
  R = find(1, 1, n);
  for (int cur : Candidate) Solve(cur);
  if (ans == INF) ans = -1;
  printf("%d\n", ans);
  return 0;
}
