#include <bits/stdc++.h>
using namespace std;
const int MAXN = 505 + 5;
const int oo = 0x3f3f3f3f;
struct Tree {
  int root;
  vector<int> g[MAXN];
  void addedge(int a, int b) {
    g[a].push_back(b);
    g[b].push_back(a);
  }
  int cnt[MAXN];
  int flow[MAXN], col[MAXN];
  int dfs(bool &flag, int x, int p = 0, int cur = 0) {
    if (cnt[x]) {
      cur = x;
    }
    col[x] = cur;
    int cost = 0;
    for (auto y : g[x]) {
      if (y != p) {
        cost += dfs(flag, y, x, cur);
      }
    }
    if (cnt[x]) {
      if (cost > cnt[x]) {
        flag = false;
      }
      flow[x] = cnt[x] - cost;
      cost = cnt[x];
    }
    return cost;
  }
} T1, T2;
template <class T>
inline bool relax(T &x, const T &y) {
  return x > y ? x = y, 1 : 0;
}
template <int MAXN>
struct Graph {
  struct Edge {
    int v, cap, cost, next;
    Edge() {}
    Edge(int _v, int _cap, int _cost, int _next)
        : v(_v), cap(_cap), cost(_cost), next(_next) {}
  };
  int n, m, s, t;
  int head[MAXN];
  vector<Edge> edge;
  void init(int n) {
    this->n = n;
    m = 0;
    memset(head, -1, sizeof(*head) * (n + 1));
    edge.clear();
  }
  void addedge(int a, int b, int c, int d) {
    edge.emplace_back(b, c, d, head[a]), head[a] = m++;
    edge.emplace_back(a, 0, -d, head[b]), head[b] = m++;
  }
  int dis[MAXN], a[MAXN], from[MAXN];
  bool vis[MAXN];
  queue<int> q;
  bool SPFA(int &flow, int &cost) {
    memset(dis, 0x3f, sizeof(*dis) * (n + 1));
    dis[s] = 0;
    a[s] = oo;
    vis[s] = true;
    q.push(s);
    while (!q.empty()) {
      int x = q.front();
      q.pop();
      vis[x] = false;
      for (int i = head[x]; ~i; i = edge[i].next) {
        Edge &e = edge[i];
        if (e.cap && relax(dis[e.v], dis[x] + e.cost)) {
          from[e.v] = i;
          a[e.v] = min(a[x], e.cap);
          if (!vis[e.v]) {
            vis[e.v] = true;
            q.push(e.v);
          }
        }
      }
    }
    if (dis[t] == oo) return false;
    flow += a[t];
    cost += dis[t] * a[t];
    int u = t;
    while (u != s) {
      edge[from[u]].cap -= a[t];
      edge[from[u] ^ 1].cap += a[t];
      u = edge[from[u] ^ 1].v;
    }
    return true;
  }
  pair<int, int> MCMF(int s, int t) {
    this->s = s;
    this->t = t;
    int flow = 0;
    int cost = 0;
    while (SPFA(flow, cost))
      ;
    return make_pair(flow, cost);
  }
};
int n;
int a[MAXN];
Graph<MAXN * 2> g;
void input() {
  scanf("%d%d%d", &n, &T1.root, &T2.root);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
  }
  for (int i = 1; i < n; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    T1.addedge(a, b);
  }
  for (int i = 1; i < n; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    T2.addedge(a, b);
  }
  int q;
  scanf("%d", &q);
  for (int i = 1; i <= q; i++) {
    int x, k;
    scanf("%d%d", &x, &k);
    T1.cnt[x] = k;
  }
  scanf("%d", &q);
  for (int i = 1; i <= q; i++) {
    int x, k;
    scanf("%d%d", &x, &k);
    T2.cnt[x] = k;
  }
}
void solve() {
  bool flag = true;
  int tot1 = T1.dfs(flag, T1.root);
  int tot2 = T2.dfs(flag, T2.root);
  if (!flag || tot1 != tot2) {
    puts("-1");
    return;
  }
  g.init(2 * n + 2);
  int s = 2 * n + 1;
  int t = 2 * n + 2;
  for (int i = 1; i <= n; i++) {
    g.addedge(s, i, T1.flow[i], 0);
    g.addedge(i + n, t, T2.flow[i], 0);
    g.addedge(T1.col[i], T2.col[i] + n, 1, -a[i]);
  }
  int flow, cost;
  tie(flow, cost) = g.MCMF(s, t);
  if (flow != tot1) {
    puts("-1");
    return;
  }
  cout << -cost << endl;
}
int main() {
  input();
  solve();
  return 0;
}
