#include <bits/stdc++.h>
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
namespace MinFlow {
struct FlowEdge {
  int next, revIdx;
  long long flow, cap, cost;
};
struct Edge {
  int next;
  long long cost, cap;
};
struct PrevData {
  int node, backIdx;
};
vector<PrevData> prev;
vector<pair<long long, long long>> dis;
vector<vector<FlowEdge>> adj;
long long minCost;
pair<long long, long long> res;
void createAdj(vector<Edge>* flowAdj, const int& n) {
  adj.clear();
  adj.resize(n);
  vector<map<pair<int, long long>, int>> v;
  v.resize(n);
  for (int i = 0; i < (n); i++)
    for (const Edge e : flowAdj[i]) {
      bool newNode = 0, newNext = 0;
      if (!v[i].count({e.next, e.cost})) {
        v[i][{e.next, e.cost}] = ((int)(adj[i]).size());
        newNode = 1;
      }
      if (!v[e.next].count({i, -e.cost})) {
        v[e.next][{i, -e.cost}] = ((int)(adj[e.next]).size());
        newNext = 1;
      }
      if (newNode)
        adj[i].push_back({e.next, v[e.next][{i, -e.cost}], 0, 0, e.cost});
      adj[i][v[i][{e.next, e.cost}]].cap += e.cap;
      if (newNext)
        adj[e.next].push_back({i, v[i][{e.next, e.cost}], 0, 0, -e.cost});
    }
}
void calcPotential(const int& s, const int& t) {
  for (int i = 0; i < (((int)(adj).size())); i++) dis[i] = make_pair(-1e18, 0);
  dis[s] = make_pair(0, 1e18);
  priority_queue<pair<pair<long long, long long>, int>> pq;
  pq.push({dis[s], s});
  while (!pq.empty()) {
    int node = pq.top().second;
    pair<long long, long long> d = pq.top().first;
    pq.pop();
    if (d < dis[node]) continue;
    for (const FlowEdge e : adj[node])
      if (e.flow < e.cap) {
        pair<long long, long long> newDis = make_pair(
            dis[node].first - e.cost, min(e.cap - e.flow, dis[node].second));
        if (newDis > dis[e.next]) {
          prev[e.next] = {node, e.revIdx};
          dis[e.next] = newDis;
          pq.push({dis[e.next], e.next});
        }
      }
  }
  for (int i = 0; i < (((int)(adj).size())); i++) dis[i].first = -dis[i].first;
  minCost += dis[t].first;
}
void backtrack(const int& s, const int& t) {
  res.first += dis[t].second;
  res.second += dis[t].second * minCost;
  for (int curr = t; curr != s; curr = prev[curr].node) {
    adj[curr][prev[curr].backIdx].flow -= dis[t].second;
    int idx = adj[curr][prev[curr].backIdx].revIdx;
    adj[prev[curr].node][idx].flow += dis[t].second;
  }
}
pair<long long, long long> calcMinFlow(vector<Edge>* flowAdj, const int& n,
                                       const int& s, const int& t) {
  createAdj(flowAdj, n);
  dis.resize(n);
  prev.resize(n);
  minCost = 0;
  res = make_pair(0LL, 0LL);
  calcPotential(s, t);
  while (1) {
    for (int i = 0; i < (((int)(adj).size())); i++)
      for (FlowEdge& e : adj[i]) e.cost += dis[i].first - dis[e.next].first;
    calcPotential(s, t);
    if (dis[t] == make_pair((long long)1e18, 0LL)) break;
    backtrack(s, t);
  }
  return res;
}
};  // namespace MinFlow
int n, r[2], req[2][500], nextUp[2][500];
long long a[500], reqFlow;
vector<int> adj[2][500];
vector<MinFlow::Edge> flowAdj[2 * 500 + 2];
void readInput() {
  cin >> n;
  for (int i = 0; i < (2); i++) {
    cin >> r[i];
    r[i]--;
  }
  for (int i = 0; i < (n); i++) cin >> a[i];
  for (int i = 0; i < (2); i++)
    for (int j = 0; j < (n - 1); j++) {
      int u, v;
      cin >> u >> v;
      u--, v--;
      adj[i][u].push_back(v);
      adj[i][v].push_back(u);
    }
  for (int i = 0; i < (2); i++) {
    int q;
    cin >> q;
    for (int j = 0; j < (q); j++) {
      int k, x;
      cin >> k >> x;
      k--;
      req[i][k] = x;
    }
  }
}
int dfsReq(int i, int node, int par, int nu) {
  if (req[i][node]) nu = node;
  nextUp[i][node] = nu;
  int curr = 0;
  for (const int next : adj[i][node])
    if (next != par) curr += dfsReq(i, next, node, nu);
  if (req[i][node] > 0) {
    if (curr > req[i][node]) {
      cout << -1 << endl;
      exit(0);
    }
    req[i][node] -= curr;
    return req[i][node] + curr;
  }
  return curr;
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  readInput();
  if (req[0][r[0]] != req[1][r[1]]) {
    cout << -1 << endl;
    return 0;
  }
  reqFlow = req[0][r[0]];
  for (int i = 0; i < (2); i++) dfsReq(i, r[i], -1, -1);
  for (int i = 0; i < (n); i++)
    if (req[0][i]) flowAdj[0].push_back({i + 1, 0, req[0][i]});
  for (int i = 0; i < (n); i++)
    if (req[1][i]) flowAdj[n + 1 + i].push_back({2 * n + 1, 0, req[1][i]});
  for (int i = 0; i < (n); i++)
    flowAdj[1 + nextUp[0][i]].push_back({n + 1 + nextUp[1][i], -a[i], 1});
  pair<long long, long long> minFlow =
      MinFlow::calcMinFlow(flowAdj, 2 * n + 2, 0, 2 * n + 1);
  if (minFlow.first != reqFlow) {
    cout << -1 << endl;
    return 0;
  }
  cout << -minFlow.second << endl;
}
