#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1010;
const long long INF = 1e15;
struct edge {
  int dest;
  long long origcap, cap, cost;
  int rev;
};
struct MinCostMaxFlow {
  vector<edge> adj[MAXN];
  long long dis[MAXN], cost;
  int source, target, iter, in_queue[MAXN];
  long long totflow;
  edge* pre[MAXN];
  MinCostMaxFlow() {}
  void AddEdge(int from, int to, long long cap, long long cost) {
    adj[from].push_back(edge{to, cap, cap, cost, (int)adj[to].size()});
    adj[to].push_back(edge{from, 0, 0, -cost, (int)adj[from].size() - 1});
  }
  bool spfa() {
    fill(dis, dis + MAXN, INF);
    fill(in_queue, in_queue + MAXN, 0);
    queue<int> q;
    pre[source] = pre[target] = 0;
    dis[source] = 0;
    q.emplace(source);
    in_queue[source] = 1;
    while (!q.empty()) {
      int x = q.front();
      long long d = dis[x];
      q.pop();
      in_queue[x] = 0;
      for (auto& e : adj[x]) {
        int y = e.dest;
        long long w = d + e.cost;
        if (e.cap < 1 || dis[y] <= w) continue;
        dis[y] = w;
        pre[y] = &e;
        if (!in_queue[y]) {
          q.push(y);
          in_queue[y] = 1;
        }
      }
    }
    edge* e = pre[target];
    if (!e) return 0;
    long long cap = e->cap;
    while (e) {
      cap = min(cap, e->cap);
      e = pre[adj[e->dest][e->rev].dest];
    }
    e = pre[target];
    while (e) {
      edge& rev = adj[e->dest][e->rev];
      e->cap -= cap;
      rev.cap += cap;
      cost += cap * e->cost;
      e = pre[rev.dest];
    }
    totflow += cap;
    return 1;
  }
  pair<long long, long long> GetMaxFlow(int S, int T) {
    source = S, target = T, cost = 0;
    totflow = 0;
    while (spfa()) {
    }
    return make_pair(totflow, cost);
  }
};
const int MAX = 512;
vector<int> adj[MAX][2];
int a[MAX];
int sum[MAX][2], boss[MAX][2], need[MAX][2];
int dfs(int u, int p, int pp, int iter) {
  sum[u][iter] = 0;
  pp = need[u][iter] > 0 ? u : pp;
  boss[u][iter] = pp;
  for (int v : adj[u][iter]) {
    if (v == p) continue;
    sum[u][iter] += dfs(v, u, pp, iter);
  }
  if (need[u][iter] > 0) return need[u][iter];
  return sum[u][iter];
}
int main() {
  int n, x, y;
  cin >> n >> x >> y;
  x--;
  y--;
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    adj[u][0].push_back(v);
    adj[v][0].push_back(u);
  }
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    adj[u][1].push_back(v);
    adj[v][1].push_back(u);
  }
  for (int i = 0; i < n; i++) need[i][0] = need[i][1] = 0;
  int q1;
  cin >> q1;
  for (int i = 0; i < q1; i++) {
    int a, b;
    cin >> a >> b;
    a--;
    need[a][0] = b;
  }
  int q2;
  cin >> q2;
  for (int i = 0; i < q2; i++) {
    int a, b;
    cin >> a >> b;
    a--;
    need[a][1] = b;
  }
  dfs(x, -1, -1, 0);
  dfs(y, -1, -1, 1);
  MinCostMaxFlow mcmf = MinCostMaxFlow();
  int source = 2 * n + 1;
  int sink = source + 1;
  for (int i = 0; i < n; i++) {
    if (need[i][0] > 0) mcmf.AddEdge(source, i, need[i][0] - sum[i][0], 0);
    if (need[i][1] > 0) mcmf.AddEdge(n + i, sink, need[i][1] - sum[i][1], 0);
    mcmf.AddEdge(boss[i][0], n + boss[i][1], 1, -a[i]);
  }
  pair<int, int> res = mcmf.GetMaxFlow(source, sink);
  bool flg = true;
  for (auto e : mcmf.adj[source]) {
    if (need[e.dest][0] > 0 && e.cap != 0) flg = false;
  }
  for (auto e : mcmf.adj[sink]) {
    if (need[e.dest - n][1] > 0 && mcmf.adj[e.dest][e.rev].cap != 0)
      flg = false;
  }
  if (flg) {
    cout << -res.second << endl;
  } else {
    cout << -1 << endl;
  }
  return 0;
}
