#include <bits/stdc++.h>
using namespace std;
int cap[1520][1020], flow[1520][1520], cost[1520][1520];
vector<int> graph[1520];
void pushEdge(int x, int y, int capacity, int currentCost) {
  cap[x][y] = capacity;
  cost[x][y] = currentCost;
  cost[y][x] = -currentCost;
  graph[x].push_back(y);
  graph[y].push_back(x);
}
class cmp {
 public:
  bool operator()(const pair<int, int> &A, const pair<int, int> &B) const {
    return A.first > B.first;
  }
};
priority_queue<pair<int, int>, vector<pair<int, int>>, cmp> pq;
pair<bool, int> addToFlow(int source, int destination, int n) {
  vector<int> last(static_cast<unsigned int>(n + 1));
  vector<int> distances(static_cast<unsigned int>(n + 1), 1000000000);
  for (int i = 1; i <= n; ++i) last[i] = i;
  distances[source] = 0;
  last[source] = 0;
  pq.push({0, source});
  while (pq.size()) {
    int dist = pq.top().first;
    int node = pq.top().second;
    pq.pop();
    if (dist != distances[node]) continue;
    for (auto x : graph[node]) {
      if (cap[node][x] == flow[node][x]) continue;
      if (distances[x] <= distances[node] + cost[node][x]) continue;
      distances[x] = distances[node] + cost[node][x];
      pq.push({distances[x], x});
      last[x] = node;
    }
  }
  int minimum = 1000000000;
  int current = destination;
  if (last[destination] == destination) return {false, -1};
  while (last[current]) {
    minimum = min(minimum,
                  cap[last[current]][current] - flow[last[current]][current]);
    current = last[current];
  }
  current = destination;
  while (last[current]) {
    flow[last[current]][current] += minimum;
    flow[current][last[current]] -= minimum;
    current = last[current];
  }
  return {true, minimum * (distances[destination])};
}
long long getMinimumCost(int source, int destination, int n) {
  long long answer = 0;
  while (true) {
    pair<int, int> ans = addToFlow(source, destination, n);
    if (!ans.first) break;
    answer += ans.second;
  }
  return answer;
}
vector<vector<int>> tree1(502);
vector<vector<int>> tree2(502);
int father1[502];
int father2[502];
int requirement1[502];
int requirement2[502];
int initialRequirements1[502];
int initialRequirements2[502];
int finalReq1[502];
int finalReq2[502];
void buildFather(int node, int father, int boss, int fathers[],
                 int requirements[], vector<vector<int>> &tree,
                 int finalReq[]) {
  if (requirements[node] >= 0) boss = node;
  fathers[node] = boss;
  int totalSubtree = 0;
  for (auto x : tree[node]) {
    if (x == father) continue;
    buildFather(x, node, boss, fathers, requirements, tree, finalReq);
    totalSubtree += requirements[x];
  }
  if (requirements[node] >= 0) {
    if (requirements[node] < totalSubtree) {
      cout << -1;
      exit(0);
    }
    finalReq[node] = requirements[node] - totalSubtree;
  } else {
    requirements[node] = totalSubtree;
    finalReq[node] = -1;
  }
}
int a[502];
int main() {
  int n, x, y;
  cin >> n >> x >> y;
  for (int i = 1; i <= n; ++i) {
    requirement1[i] = requirement2[i] = -1;
    initialRequirements1[i] = requirement1[i];
    initialRequirements2[i] = requirement2[i];
    cin >> a[i];
  }
  for (int i = 1; i < n; ++i) {
    int x, y;
    cin >> x >> y;
    tree1[x].push_back(y);
    tree1[y].push_back(x);
  }
  for (int i = 1; i < n; ++i) {
    int x, y;
    cin >> x >> y;
    tree2[x].push_back(y);
    tree2[y].push_back(x);
  }
  int q1;
  cin >> q1;
  for (int i = 1; i <= q1; ++i) {
    int node, ports;
    cin >> node >> ports;
    requirement1[node] = ports;
    initialRequirements1[node] = requirement1[node];
  }
  int q2;
  cin >> q2;
  for (int i = 1; i <= q2; ++i) {
    int node, ports;
    cin >> node >> ports;
    requirement2[node] = ports;
    initialRequirements2[node] = requirement2[node];
  }
  buildFather(x, -1, x, father1, requirement1, tree1, finalReq1);
  buildFather(y, -1, y, father2, requirement2, tree2, finalReq2);
  int source = 1;
  int destination = 3 * n + 2;
  for (int i = 2; i <= n + 1; ++i) {
    if (initialRequirements1[i - 1] >= 0) {
      pushEdge(source, i, finalReq1[i - 1], 0);
    }
  }
  for (int i = 1; i <= n; ++i) {
    pushEdge(i + n + 1, father2[i] + 2 * n + 1, 1, -a[i]);
    pushEdge(father1[i] + 1, i + n + 1, 1, -a[i]);
  }
  for (int i = 1; i <= n; ++i) {
    if (initialRequirements2[i] >= 0) {
      pushEdge(2 * n + 1 + i, destination, finalReq2[i], 0);
    }
  }
  long long minCost = getMinimumCost(source, destination, destination);
  for (int i = 2; i <= n + 1; ++i) {
    if (requirement1[i - 1] >= 0) {
      if (flow[source][i] != cap[source][i]) {
        cout << -1;
        return 0;
      }
    }
  }
  for (int i = 1; i <= n; ++i) {
    if (requirement1[i] >= 0) {
      if (flow[2 * n + 1 + i][destination] != cap[2 * n + 1 + i][destination]) {
        cout << -1;
        return 0;
      }
    }
  }
  cout << -minCost / 2;
  return 0;
}
