#include <bits/stdc++.h>
using namespace std;
using namespace std;
template <typename T>
void pfill(T *pst, const T *ped, T val) {
  for (; pst != ped; *(pst++) = val)
    ;
}
typedef class Edge {
 public:
  int ed, nx, r, c;
  Edge(int ed = 0, int nx = 0, int r = 0, int c = 0)
      : ed(ed), nx(nx), r(r), c(c) {}
} Edge;
typedef class MapManager {
 public:
  int *h;
  vector<Edge> es;
  MapManager() {}
  MapManager(int n) {
    h = new int[(n + 1)];
    pfill(h, h + n + 1, -1);
  }
  void addEdge(int u, int v, int r, int c) {
    es.push_back(Edge(v, h[u], r, c));
    h[u] = (signed)es.size() - 1;
  }
  void addArc(int u, int v, int cap, int c) {
    addEdge(u, v, cap, c);
    addEdge(v, u, 0, -c);
  }
  Edge &operator[](int p) { return es[p]; }
} MapManager;
const signed int inf = (signed)(~0u >> 1);
typedef class Network {
 public:
  int S, T;
  MapManager g;
  int *le;
  int *f, *mf;
  bool *vis;
  int flow;
  Network() {}
  Network(int S, int T) : S(S), T(T), g(T), flow(0) {
    f = new int[(T + 1)];
    le = new int[(T + 1)];
    mf = new int[(T + 1)];
    vis = new bool[(T + 1)];
    pfill(vis, vis + T, false);
  }
  int spfa() {
    queue<int> que;
    pfill(f, f + T + 1, inf);
    que.push(S);
    f[S] = 0, le[S] = -1, mf[S] = inf;
    while (!que.empty()) {
      int e = que.front();
      que.pop();
      vis[e] = false;
      for (int i = g.h[e], eu, w; ~i; i = g[i].nx) {
        if (!g[i].r) continue;
        eu = g[i].ed, w = f[e] + g[i].c;
        if (w < f[eu]) {
          f[eu] = w, le[eu] = i, mf[eu] = min(mf[e], g[i].r);
          if (!vis[eu]) {
            vis[eu] = true;
            que.push(eu);
          }
        }
      }
    }
    if (f[T] == inf) return inf;
    int rt = 0;
    flow += mf[T];
    for (int p = T, e; ~le[p]; p = g[e ^ 1].ed) {
      e = le[p];
      g[e].r -= mf[T];
      g[e ^ 1].r += mf[T];
      rt += mf[T] * g[e].c;
    }
    return rt;
  }
  int min_cost() {
    int rt = 0, delta;
    while ((delta = spfa()) != inf) {
      rt += delta;
    }
    return rt;
  }
} Network;
typedef class Tree {
 public:
  int n, rt;
  int *lim, *fa;
  vector<int> *g;
  Tree() {}
  Tree(int n, int rt) : n(n), rt(rt) {
    fa = new int[(n + 1)];
    lim = new int[(n + 1)];
    g = new vector<int>[(n + 1)];
    pfill(lim + 1, lim + n + 1, -1);
  }
  int dfs(int p, int ls) {
    int rt = 0;
    fa[p] = ls;
    for (auto e : g[p]) {
      if (e ^ ls) {
        rt += dfs(e, p);
      }
    }
    if (~lim[p]) {
      lim[p] -= rt;
      return rt + lim[p];
    }
    return rt;
  }
  void init() {
    for (int i = 1, u, v; i < n; i++) {
      scanf("%d%d", &u, &v);
      g[u].push_back(v);
      g[v].push_back(u);
    }
  }
  void init_limit() {
    int q, a, x;
    scanf("%d", &q);
    while (q--) {
      scanf("%d%d", &a, &x);
      lim[a] = x;
    }
    dfs(rt, 0);
  }
  int get_domination(int p) {
    while (lim[p] == -1) {
      p = fa[p];
    }
    return p;
  }
} Tree;
int n;
int *w;
Tree tr1, tr2;
inline void init() {
  int x, y;
  scanf("%d%d%d", &n, &x, &y);
  w = new int[(n + 1)];
  for (int i = 1; i <= n; i++) {
    scanf("%d", w + i);
  }
  tr1 = Tree(n, x);
  tr2 = Tree(n, y);
  tr1.init();
  tr2.init();
  tr1.init_limit();
  tr2.init_limit();
}
inline void solve() {
  Network network(0, 2 * n + 1);
  MapManager &g = network.g;
  int sums = 0, sumt = 0;
  for (int i = 1; i <= n; i++) {
    if (tr1.lim[i] > 0) {
      g.addArc(network.S, i, tr1.lim[i], 0);
      sums += tr1.lim[i];
    }
  }
  for (int i = 1; i <= n; i++) {
    if (tr2.lim[i] > 0) {
      g.addArc(i + n, network.T, tr2.lim[i], 0);
      sumt += tr2.lim[i];
    }
  }
  if (sums != sumt) {
    puts("-1");
    return;
  }
  for (int i = 1; i <= n; i++) {
    int x = tr1.get_domination(i);
    int y = tr2.get_domination(i);
    g.addArc(x, y + n, 1, -w[i]);
  }
  int ans = -network.min_cost();
  if (network.flow == sums) {
    printf("%d\n", ans);
  } else {
    puts("-1");
  }
}
int main() {
  init();
  solve();
  return 0;
}
