#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3fffffff;
const int SINF = 0x7fffffff;
const long long LINF = 0x3fffffffffffffff;
const long long SLINF = 0x7fffffffffffffff;
const int MINF = 0x3f3f3f3f;
const int MAXN = 507;
const int MAXV = 1007;
const int MAXE = 100007;
struct eT {
  void setd(int _u, int _v, int _f, int _w, int _l) {
    u = _u, v = _v, f = _f, w = _w, last = _l;
  }
  int u, v, f, w, last;
} edge[MAXE];
int ke, la[MAXV], S = MAXV - 1, T = MAXV - 2;
void addedge(int u, int v, int f, int w) {
  edge[ke].setd(u, v, f, w, la[u]);
  la[u] = ke++;
  edge[ke].setd(v, u, 0, -w, la[v]);
  la[v] = ke++;
}
struct tT {
  tT() { memset(la, -1, sizeof(la)); }
  void addedge(int u, int v) {
    edge[ke].setd(u, v, la[u]);
    la[u] = ke++;
    edge[ke].setd(v, u, la[v]);
    la[v] = ke++;
  }
  void inputtree(int n) {
    int u, v;
    for (int i = 1; i < n; ++i) {
      scanf("%d%d", &u, &v);
      addedge(u, v);
    }
  }
  void inputlim() {
    int q;
    scanf("%d", &q);
    int k, x;
    for (int i = 0; i < q; ++i) {
      scanf("%d%d", &k, &x);
      lim[k] = x;
    }
  }
  int build(int t) { dfs(rt, -1, 0, t); }
  void dfs(int now, int fa, int top, int t) {
    bool clim = false;
    if (lim[now]) {
      clim = true;
      if (top) lim[top] -= lim[now];
      top = now;
    }
    bel[now] = top;
    for (int i = la[now]; ~i; i = edge[i].last)
      if (edge[i].v ^ fa) dfs(edge[i].v, now, top, t);
    if (clim) {
      if (lim[now] < 0) {
        printf("-1\n");
        exit(0);
      }
      if (!t)
        ::addedge(S, ((now) << 1), lim[now], 0);
      else
        ::addedge(((now) << 1 | 1), T, lim[now], 0);
    }
  }
  struct eT {
    void setd(int _u, int _v, int _l) { u = _u, v = _v, last = _l; }
    int u, v, last;
  } edge[MAXN * 2];
  int ke, la[MAXN];
  int lim[MAXN], bel[MAXN];
  int rt;
} t1, t2;
int n;
int a[MAXN];
int q[MAXV], dist[MAXV], pre[MAXV];
bool inq[MAXV];
void init();
void input();
void work();
pair<int, int> mcmf();
int main() {
  init();
  input();
  work();
}
void init() { ios::sync_with_stdio(false); }
void input() {
  scanf("%d%d%d", &n, &t1.rt, &t2.rt);
  for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
  t1.inputtree(n);
  t2.inputtree(n);
  t1.inputlim();
  t2.inputlim();
}
void work() {
  if (t1.lim[t1.rt] ^ t2.lim[t2.rt]) {
    printf("-1\n");
    return;
  }
  int expected = t1.lim[t1.rt];
  memset(la, -1, sizeof(la));
  t1.build(0);
  t2.build(1);
  for (int i = 1; i <= n; ++i)
    addedge(((t1.bel[i]) << 1), ((t2.bel[i]) << 1 | 1), 1, -a[i]);
  pair<int, int> ret = mcmf();
  printf("%d\n", (ret.first ^ expected) ? -1 : -ret.second);
}
void nxt(int &x) { ((++x) < MAXN) ? x : (x = 0); }
pair<int, int> mcmf() {
  int l, r, now, v, f, mini, af = 0, ans = 0;
  while (1) {
    memset(dist, MINF, sizeof(dist));
    memset(inq, false, sizeof(inq));
    l = r = 0;
    q[r++] = S;
    dist[S] = 0;
    while (l ^ r) {
      now = q[l];
      nxt(l);
      inq[now] = false;
      for (int i = la[now]; ~i; i = edge[i].last) {
        if (edge[i].f && dist[v = edge[i].v] > dist[now] + edge[i].w) {
          dist[v] = dist[now] + edge[i].w;
          pre[v] = i;
          if (!inq[v]) {
            q[r] = v;
            nxt(r);
            inq[v] = true;
          }
        }
      }
    }
    if (dist[T] == MINF) break;
    mini = INF;
    for (int i = T; i ^ S; i = edge[pre[i]].u)
      mini = (((mini) < (edge[pre[i]].f)) ? (mini) : (edge[pre[i]].f));
    af += mini;
    ans += mini * dist[T];
    for (int i = T; i ^ S; i = edge[pre[i]].u)
      edge[pre[i]].f -= mini, edge[pre[i] ^ 1].f += mini;
  }
  return make_pair(af, ans);
}
