#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
struct MCF {
  int n;
  vector<int> prio, curflow, prevedge, prevnode, pot;
  priority_queue<long long, vector<long long>, greater<long long>> q;
  struct edge {
    int to, rev;
    int f, cap, cost;
  };
  vector<vector<edge>> g;
  MCF(int n)
      : n(n), prio(n), curflow(n), prevedge(n), prevnode(n), pot(n), g(n) {}
  void add_edge(int s, int t, int cap, int cost) {
    g[s].push_back((edge){t, int((g[t]).size()), 0, cap, cost});
    g[t].push_back((edge){s, int((g[s]).size()) - 1, 0, 0, -cost});
  }
  pair<int, int> get_flow(int s, int t) {
    int flow = 0, flowcost = 0;
    while (1) {
      q.push(s);
      fill((prio).begin(), (prio).end(), INF);
      prio[s] = 0;
      curflow[s] = INF;
      while (!q.empty()) {
        long long cur = q.top();
        int d = cur >> 32, u = cur;
        q.pop();
        if (d != prio[u]) continue;
        for (int i = 0; i < int((g[u]).size()); ++i) {
          edge &e = g[u][i];
          int v = e.to;
          if (e.cap <= e.f) continue;
          int nprio = prio[u] + e.cost + pot[u] - pot[v];
          if (prio[v] > nprio) {
            prio[v] = nprio;
            q.push(((long long)nprio << 32) + v);
            prevnode[v] = u;
            prevedge[v] = i;
            curflow[v] = min(curflow[u], e.cap - e.f);
          }
        }
      }
      if (prio[t] == INF) break;
      for (int i = (0), qwerty = (n); i < qwerty; i++) pot[i] += prio[i];
      int df = min(curflow[t], INF - flow);
      flow += df;
      for (int v = t; v != s; v = prevnode[v]) {
        edge &e = g[prevnode[v]][prevedge[v]];
        e.f += df;
        g[v][e.rev].f -= df;
        flowcost += df * e.cost;
      }
    }
    return {flow, flowcost};
  }
};
struct Graph {
  int n, root;
  vector<vector<int>> g;
  vector<int> ks;
  Graph(int n, int root) : n(n), root(root - 1), g(n), ks(n) {}
  vector<pair<int, vector<int>>> gs, ts;
  int build(int u, int p) {
    if (ks[u]) ts.push_back({ks[u], {u}});
    int val = 0;
    for (int v : g[u])
      if (v != p) val += build(v, u);
    if (ks[u] && val > ks[u]) {
      cout << "-1\n";
      exit(0);
    }
    if (!ks[u])
      ts.back().second.push_back(u);
    else
      ts.back().first -= val, gs.push_back(ts.back()), ts.pop_back();
    return ks[u] ? ks[u] : val;
  }
  void read() {
    for (int x = (1), qwerty = (n); x < qwerty; x++) {
      int u, v;
      cin >> u >> v;
      u--;
      v--;
      g[u].push_back(v);
      g[v].push_back(u);
    }
  }
  void read_qs() {
    int q;
    cin >> q;
    for (int x = (0), qwerty = (q); x < qwerty; x++) {
      int k, u;
      cin >> u >> k;
      u--;
      ks[u] = k;
    }
    build(root, -1);
  }
};
const int N = 505;
long long A[N];
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n, X, Y;
  cin >> n >> X >> Y;
  Graph g1(n, X), g2(n, Y);
  for (int x = (0), qwerty = (n); x < qwerty; x++) cin >> A[x];
  g1.read();
  g2.read();
  g1.read_qs();
  g2.read_qs();
  MCF nt(int((g1.gs).size()) + int((g2.gs).size()) + n + 2);
  if (g1.ks[X - 1] != g2.ks[Y - 1]) {
    cout << "-1\n";
    exit(0);
  }
  for (int x = (0), qwerty = (int((g1.gs).size())); x < qwerty; x++) {
    nt.add_edge(0, x + 1, g1.gs[x].first, 0);
  }
  int nodes = 0;
  nodes += int((g1.gs).size());
  for (int x = (0), qwerty = (int((g1.gs).size())); x < qwerty; x++) {
    for (int v : g1.gs[x].second) nt.add_edge(x + 1, nodes + v + 1, 1, 0);
  }
  nodes += n;
  for (int x = (0), qwerty = (int((g2.gs).size())); x < qwerty; x++) {
    nt.add_edge(nodes + x + 1, nodes + int((g2.gs).size()) + 1, g2.gs[x].first,
                0);
    for (int v : g2.gs[x].second)
      nt.add_edge(int((g1.gs).size()) + 1 + v, nodes + x + 1, 1, -A[v]);
  }
  nodes += int((g2.gs).size()) + 2;
  auto ans = nt.get_flow(0, nodes - 1);
  if (ans.first != g1.ks[X - 1])
    cout << "-1\n";
  else
    cout << -ans.second << "\n";
}
