#include <bits/stdc++.h>
int w[503];
struct Tree {
  int root, cntlim[503], fir[503], to[1003], nxt[1003], edcnt, limcnt;
  std::vector<int> lim[503];
  Tree() : edcnt(0) { memset(cntlim, -1, sizeof cntlim); }
  void AddEdge(int u, int v) {
    to[++edcnt] = v, nxt[edcnt] = fir[u], fir[u] = edcnt;
    to[++edcnt] = u, nxt[edcnt] = fir[v], fir[v] = edcnt;
  }
  void mark(int v, int fa) {
    lim[limcnt].push_back(v);
    for (int i = fir[v]; i; i = nxt[i])
      if (to[i] != fa && cntlim[to[i]] == -1) mark(to[i], v);
  }
  int getlim(int v, int fa) {
    int tot = 0;
    if (cntlim[v] >= 0) {
      for (int i = fir[v]; i; i = nxt[i])
        if (to[i] != fa) {
          tot += getlim(to[i], v);
        }
      if (cntlim[v] - tot < 0) exit(puts("-1") & 0);
      lim[limcnt].push_back(cntlim[v] - tot);
      mark(v, fa);
      limcnt++;
      return cntlim[v];
    }
    for (int i = fir[v]; i; i = nxt[i])
      if (to[i] != fa) {
        tot += getlim(to[i], v);
      }
    return tot;
  }
};
struct WiFi_flow {
  int S, T, fir[1601], cap[6001], cost[6001], to[6001], nxt[6001], edcnt;
  WiFi_flow() : edcnt(1) {}
  void AddEdge(int u, int v, int c, int w) {
    to[++edcnt] = v, cap[edcnt] = c, cost[edcnt] = w, nxt[edcnt] = fir[u],
    fir[u] = edcnt;
    to[++edcnt] = u, cap[edcnt] = 0, cost[edcnt] = -w, nxt[edcnt] = fir[v],
    fir[v] = edcnt;
  }
  int lp[1601], fa[1601];
  struct Node {
    int v, lp;
    bool operator<(const Node &cmp) const { return lp > cmp.lp; }
  };
  bool spfa() {
    int cur, t, i;
    Node no = {S, 0};
    std::priority_queue<Node> pq;
    memset(lp, 0x3f, sizeof lp);
    memset(fa, 0, sizeof fa);
    lp[S] = 0;
    pq.push(no);
    while (!pq.empty()) {
      cur = pq.top().v;
      pq.pop();
      for (i = fir[cur]; i; i = nxt[i])
        if (cap[i] > 0 && lp[t = to[i]] > lp[cur] + cost[i]) {
          lp[t] = lp[cur] + cost[i], fa[t] = i;
          no.v = t, no.lp = lp[t], pq.push(no);
        }
    }
    return lp[T] < 0x3f3f3f3f;
  }
  int max_cost_max_flow(int &cost) {
    int v, flow, maxflow = cost = 0;
    while (spfa()) {
      v = T, flow = 0x7f7f7f7f;
      for (v = T; v != S; v = to[fa[v] ^ 1])
        if (flow > cap[fa[v]]) flow = cap[fa[v]];
      for (v = T; v != S; v = to[fa[v] ^ 1])
        cap[fa[v]] -= flow, cap[fa[v] ^ 1] += flow;
      maxflow += flow, cost += lp[T] * flow;
    }
    return maxflow;
  }
};
Tree red, blue;
WiFi_flow nf;
int main() {
  int n, u, v, c1, c2, i, j, ans;
  scanf("%d%d%d", &n, &red.root, &blue.root);
  for (i = 1; i <= n; i++) scanf("%d", w + i);
  for (i = 1; i < n; i++) scanf("%d%d", &u, &v), red.AddEdge(u, v);
  for (i = 1; i < n; i++) scanf("%d%d", &u, &v), blue.AddEdge(u, v);
  scanf("%d", &i);
  while (i--) scanf("%d%d", &u, &v), red.cntlim[u] = v;
  scanf("%d", &i);
  while (i--) scanf("%d%d", &u, &v), blue.cntlim[u] = v;
  if (red.cntlim[red.root] != blue.cntlim[blue.root]) return puts("-1"), 0;
  red.getlim(red.root, 0), blue.getlim(blue.root, 0);
  c1 = red.limcnt, c2 = blue.limcnt;
  nf.S = 1, nf.T = n + c1 + c2 + 2;
  for (i = 0; i < c1; i++) {
    nf.AddEdge(nf.S, i + 2, red.lim[i][0], 0);
    for (j = 1; j < red.lim[i].size(); j++)
      nf.AddEdge(i + 2, c1 + 1 + red.lim[i][j], 1, -w[red.lim[i][j]]);
  }
  for (i = 0; i < c2; i++) {
    nf.AddEdge(c1 + n + 2 + i, nf.T, blue.lim[i][0], 0);
    for (j = 1; j < blue.lim[i].size(); j++)
      nf.AddEdge(c1 + 1 + blue.lim[i][j], c1 + n + 2 + i, 1, 0);
  }
  if (nf.max_cost_max_flow(ans) < red.cntlim[red.root])
    puts("-1");
  else
    printf("%d", -ans);
  return 0;
}
