#include <bits/stdc++.h>
using namespace std;
const int N = 510;
const int M = 1010 * 1010;
const int inf_ = 0x3f;
struct Flow {
  struct node {
    int from, to, next;
    int val;
    int flow;
  } e[M << 1];
  int head[N << 1], S, T, cnt, vis[N << 1], from[N << 1];
  queue<int> q;
  long long dis[N << 1], mxflow, micost;
  void init(int ss, int tt) {
    S = ss, T = tt, memset(head, -1, sizeof(head));
    mxflow = micost = 0;
  }
  void add(int x, int y, int v, int f) {
    e[cnt] = node{x, y, head[x], v, f};
    head[x] = cnt++;
  }
  void addedge(int x, int y, int v, int f) {
    add(x, y, v, f);
    add(y, x, -v, 0);
  }
  int spfa() {
    memset(vis, 0, sizeof(vis));
    memset(dis, inf_, sizeof(dis));
    dis[S] = 0;
    q.push(S);
    vis[S] = 1, from[S] = from[T] = -1;
    while (!q.empty()) {
      int x = q.front();
      q.pop();
      vis[x] = 0;
      for (int i = head[x]; i != -1; i = e[i].next) {
        int to1 = e[i].to;
        if (e[i].flow > 0 && dis[to1] > dis[x] + e[i].val) {
          dis[to1] = dis[x] + e[i].val;
          from[to1] = i;
          if (!vis[to1]) q.push(to1), vis[to1] = 1;
        }
      }
    }
    return from[T] != -1;
  }
  void mcmf() {
    int i = from[T], x;
    memset(&x, inf_, sizeof(x));
    while (i != -1) x = min(x, e[i].flow), i = from[e[i].from];
    i = from[T];
    mxflow += x;
    while (i != -1) {
      micost += e[i].val * x;
      e[i].flow -= x;
      e[i ^ 1].flow += x;
      i = from[e[i].from];
    }
  }
  void work() {
    while (spfa()) mcmf();
  }
  void get_ans() { printf("%lld\n", -micost); }
} G;
struct tree {
  struct node {
    int to, next;
  } e[N << 1];
  int head[N], cnt, fa[N], par[N], q[N];
  void init() { memset(head, -1, sizeof(head)); }
  void add(int x, int y) {
    e[cnt] = node{y, head[x]};
    head[x] = cnt++;
  }
  void dfs(int x, int from, int lst) {
    if (from && q[x])
      q[lst] -= q[x], par[x] = lst = x;
    else
      par[x] = lst;
    for (int i = head[x]; i != -1; i = e[i].next) {
      int to1 = e[i].to;
      if (to1 != from) dfs(to1, x, lst);
    }
  }
  bool check(int n) {
    for (int i = 1; i <= n; ++i)
      if (q[i] < 0) return 0;
    return 1;
  }
} t[2];
int a[1010];
int main() {
  int n, ro1, ro2;
  G.init(0, 1001);
  t[0].init(), t[1].init();
  scanf("%d%d%d", &n, &ro1, &ro2);
  for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
  for (int i = 1, x, y; i < n; ++i)
    scanf("%d%d", &x, &y), t[0].add(x, y), t[0].add(y, x);
  for (int i = 1, x, y; i < n; ++i)
    scanf("%d%d", &x, &y), t[1].add(x, y), t[1].add(y, x);
  int q, sum = 0;
  scanf("%d", &q);
  for (int i = 1, x, k; i <= q; ++i) scanf("%d%d", &x, &k), t[0].q[x] = k;
  scanf("%d", &q);
  for (int i = 1, x, k; i <= q; ++i) scanf("%d%d", &x, &k), t[1].q[x] = k;
  if (t[0].q[ro1] != t[1].q[ro2]) return puts("-1"), 0;
  sum = t[0].q[ro1];
  t[0].dfs(ro1, 0, ro1);
  t[1].dfs(ro2, 0, ro2);
  if (!t[0].check(n) || !t[1].check(n)) return puts("-1"), 0;
  for (int i = 1; i <= n; ++i) {
    G.addedge(t[0].par[i], t[1].par[i] + n, -a[i], 1);
    G.addedge(G.S, i, 0, t[0].q[i]);
    G.addedge(i + n, G.T, 0, t[1].q[i]);
  }
  G.work();
  if (G.mxflow != sum) return puts("-1"), 0;
  G.get_ans();
  return 0;
}
