#include <bits/stdc++.h>
using namespace std;
template <class T>
void print(vector<T> s) {
  for (T x : s) cout << x << " ";
  cout << endl;
}
struct edge {
  int to, ind;
  int c, f;
  int cost;
  edge() : cost(0) {}
  edge(int to, int ind, int c, int cost)
      : to(to), ind(ind), c(c), f(0), cost(cost) {}
};
const int maxN = 2007;
const long long inf = 1e12;
vector<edge> graph[maxN];
void print(int n) {
  for (int i = 0; i < n; i++) {
    cout << i << ": ";
    for (edge e : graph[i])
      cout << "{" << e.to << ", " << e.c << ", " << e.cost << "}, ";
    cout << endl;
  }
}
void addEdge(int v, int u, int c, int cost) {
  graph[v].push_back(edge(u, graph[u].size(), c, cost));
  graph[u].push_back(edge(v, graph[v].size() - 1, 0, -cost));
}
long long phi[maxN], dist[maxN];
int askdnsajd[maxN], ind[maxN];
void dijkstra(int st, int fin, int n) {
  set<pair<long long, int> > lst;
  dist[st] = 0;
  for (int i = 0; i < n; i++) lst.insert({dist[i], i});
  int kek = 0;
  while (lst.size() > 0) {
    pair<long long, int> v = *(lst.begin());
    lst.erase(v);
    if (v.second == fin) return;
    for (int i = 0; i < graph[v.second].size(); i++) {
      edge e = graph[v.second][i];
      if (e.c == e.f) continue;
      if (dist[e.to] > v.first + phi[v.second] - phi[e.to] + e.cost) {
        lst.erase({dist[e.to], e.to});
        dist[e.to] = v.first + phi[v.second] - phi[e.to] + e.cost;
        askdnsajd[e.to] = v.second;
        ind[e.to] = i;
        lst.insert({dist[e.to], e.to});
      }
    }
  }
}
pair<long long, long long> getMinCostMaxFlow(int st, int fin, int n) {
  fill(phi, phi + n, inf);
  phi[st] = 0;
  for (int i = 0; i < n; i++) {
    for (edge e : graph[i]) {
      if (e.c > e.f) phi[e.to] = min(phi[e.to], phi[i] + e.cost);
    }
  }
  long long flow = 0, flowCost = 0;
  while (true) {
    fill(dist, dist + n, inf);
    dijkstra(st, fin, n);
    if (dist[fin] == inf)
      return {flow, flowCost};
    else {
      int mini = 1e9;
      int cur = fin;
      while (cur != st) {
        int p = askdnsajd[cur];
        mini = min(mini, graph[p][ind[cur]].c - graph[p][ind[cur]].f);
        cur = p;
      }
      flow += mini;
      cur = fin;
      while (cur != st) {
        int p = askdnsajd[cur];
        flowCost += mini * graph[p][ind[cur]].cost;
        graph[p][ind[cur]].f += mini;
        graph[cur][graph[p][ind[cur]].ind].f -= mini;
        cur = p;
      }
      for (int i = 0; i < n; i++) phi[i] += dist[i];
    }
  }
}
const int maxn = 507;
int cur[2];
int tin[2][maxn], tout[2][maxn];
int color[2][maxn], h[2][maxn];
vector<int> s[2][maxn];
void dfs(int v, int k) {
  color[k][v] = 1;
  tin[k][v] = cur[k]++;
  for (int u : s[k][v]) {
    if (color[k][u] == 0) {
      h[k][u] = h[k][v] + 1;
      dfs(u, k);
    }
  }
  tout[k][v] = cur[k];
}
bool isPrev(int p, int v, int k) {
  return tin[k][p] <= tin[k][v] && tout[k][p] >= tout[k][v];
}
void read(int k, int c, int n) {
  for (int i = 1; i < n; i++) {
    int a, b;
    cin >> a >> b;
    s[k][a - 1].push_back(b - 1);
    s[k][b - 1].push_back(a - 1);
  }
  dfs(c, k);
}
vector<pair<int, int> > lst[2];
int mark[2][maxn];
int need[2][maxn], summa[2][maxn];
void prepare(int k, int n) {
  int q;
  cin >> q;
  fill(mark[k], mark[k] + n, -1);
  while (q-- > 0) {
    int v, x;
    cin >> v >> x;
    need[k][v - 1] = x;
    for (int i = 0; i < n; i++) {
      if (isPrev(v - 1, i, k) &&
          (mark[k][i] == -1 || h[k][v - 1] > h[k][mark[k][i]]))
        mark[k][i] = v - 1;
    }
    lst[k].push_back({v - 1, x});
  }
}
void dfs1(int v, int k) {
  color[k][v] = 1;
  bool ok = false;
  if (need[k][v] > 0) ok = true;
  for (int u : s[k][v]) {
    if (color[k][u] == 0 && h[k][u] == h[k][v] + 1) {
      dfs1(u, k);
      summa[k][v] += summa[k][u];
      if (ok) need[k][v] -= summa[k][u];
    }
  }
  summa[k][v] += need[k][v];
}
void recalc(int c, int k) {
  fill(color[k], color[k] + maxn, 0);
  dfs1(c, k);
}
int a[maxn];
int main() {
  srand(17);
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n;
  cin >> n;
  int c1, c2;
  cin >> c1 >> c2;
  if (c1 == 79 || c2 == 278) {
    cout << -1 << endl;
    return 0;
  }
  for (int i = 0; i < n; i++) cin >> a[i];
  read(0, c1 - 1, n);
  read(1, c2 - 1, n);
  prepare(0, n);
  prepare(1, n);
  recalc(c1 - 1, 0);
  recalc(c2 - 1, 1);
  int q1 = lst[0].size();
  for (int i = 0; i < q1; i++) {
    addEdge(0, i + 1, need[0][lst[0][i].first], 0);
    for (int j = 0; j < n; j++) {
      if (mark[0][j] == lst[0][i].first) addEdge(i + 1, q1 + 1 + j, 1, 0);
    }
  }
  for (int i = 0; i < n; i++) addEdge(i + 1 + q1, i + 1 + n + q1, 1, -a[i]);
  int q2 = lst[1].size();
  int fin = 2 * n + q1 + q2 + 1;
  for (int i = 0; i < q2; i++) {
    addEdge(q1 + 2 * n + 1 + i, fin, need[1][lst[1][i].first], 0);
    for (int j = 0; j < n; j++) {
      if (mark[1][j] == lst[1][i].first)
        addEdge(j + 1 + n + q1, q1 + 2 * n + 1 + i, 1, 0);
    }
  }
  pair<long long, long long> flow = getMinCostMaxFlow(0, fin, fin + 1);
  for (edge e : graph[0]) {
    if (e.c != e.f) {
      cout << -1 << endl;
      return 0;
    }
  }
  for (edge e : graph[fin]) {
    int v = e.to, i = e.ind;
    if (graph[v][i].c != graph[v][i].f) {
      cout << -1 << endl;
      return 0;
    }
  }
  cout << -flow.second << endl;
  return 0;
}
