#include <bits/stdc++.h>
using namespace std;
int const INF = (int)1e9 + 1e3;
long long const INFL = (long long)1e18 + 1e6;
mt19937 tw(9450189);
uniform_int_distribution<long long> ll_distr;
long long rnd(long long a, long long b) {
  return ll_distr(tw) % (b - a + 1) + a;
}
struct edge {
  int f, c, cost;
  edge(int _c, int _cost) : f(0), c(_c), cost(_cost) {}
};
vector<edge> edges;
vector<vector<pair<int, int>>> graph;
int add_node() {
  graph.push_back({});
  return ((int)graph.size()) - 1;
}
void add_edge(int a, int b, int c, int cost) {
  graph[a].push_back({b, ((int)edges.size())});
  edges.push_back(edge(c, cost));
  graph[b].push_back({a, ((int)edges.size())});
  edges.push_back(edge(0, -cost));
}
vector<long long> dist;
vector<bool> in_queue;
vector<pair<int, int>> from;
pair<int, long long> push_flow(int s, int t) {
  queue<int> qu;
  qu.push(s);
  fill(dist.begin(), dist.end(), INFL);
  dist[s] = 0;
  while (((int)qu.size())) {
    int v = qu.front();
    in_queue[v] = false;
    qu.pop();
    for (auto to : graph[v]) {
      if (edges[to.second].f < edges[to.second].c &&
          dist[to.first] > dist[v] + edges[to.second].cost) {
        dist[to.first] = dist[v] + edges[to.second].cost;
        from[to.first] = {v, to.second};
        if (!in_queue[to.first]) {
          qu.push(to.first);
          in_queue[to.first] = true;
        }
      }
    }
  }
  if (dist[t] == INFL) {
    return {0, 0};
  }
  int f = INF;
  long long cost = 0;
  int cur = t;
  while (cur != s) {
    f = min(f, edges[from[cur].second].c - edges[from[cur].second].f);
    cur = from[cur].first;
  }
  cur = t;
  while (cur != s) {
    edges[from[cur].second].f += f;
    edges[from[cur].second ^ 1].f -= f;
    cost += (long long)f * edges[from[cur].second].cost;
    cur = from[cur].first;
  }
  return {f, cost};
}
void solve() {
  int n, x, y;
  cin >> n >> x >> y;
  --x;
  --y;
  vector<int> cost;
  for (int i = 0; i < n; ++i) {
    int num;
    cin >> num;
    cost.push_back(num);
  }
  vector<vector<int>> graph1(n), graph2(n);
  for (int i = 0; i < n - 1; ++i) {
    int a, b;
    cin >> a >> b;
    --a;
    --b;
    graph1[a].push_back(b);
    graph1[b].push_back(a);
  }
  for (int i = 0; i < n - 1; ++i) {
    int a, b;
    cin >> a >> b;
    --a;
    --b;
    graph2[a].push_back(b);
    graph2[b].push_back(a);
  }
  int q1, q2;
  vector<int> here1(n, -1), here2(n, -1);
  cin >> q1;
  for (int i = 0; i < q1; ++i) {
    int v, q;
    cin >> v >> q;
    --v;
    here1[v] = q;
  }
  cin >> q2;
  for (int i = 0; i < q2; ++i) {
    int v, q;
    cin >> v >> q;
    --v;
    here2[v] = q;
  }
  if (here1[x] != here2[y]) {
    cout << "-1\n";
    return;
  }
  vector<pair<vector<int>, int>> groups;
  vector<int> visited;
  int sum = 0;
  function<void(int, int, vector<vector<int>> const&, vector<int> const&)>
      dfs0 = [&](int v, int p, vector<vector<int>> const& g,
                 vector<int> const& here) {
        visited.push_back(v);
        for (int to : g[v]) {
          if (to != p) {
            if (here[to] == -1) {
              dfs0(to, v, g, here);
            } else {
              sum += here[to];
            }
          }
        }
      };
  function<void(int, int, vector<vector<int>> const&, vector<int> const&)> dfs =
      [&](int v, int p, vector<vector<int>> const& g, vector<int> const& here) {
        if (here[v] != -1) {
          visited.clear();
          sum = 0;
          dfs0(v, p, g, here);
          if (sum > here[v]) {
            cout << "-1\n";
            exit(0);
          }
          groups.push_back({visited, here[v] - sum});
        }
        for (int to : g[v]) {
          if (to != p) {
            dfs(to, v, g, here);
          }
        }
      };
  int s = add_node();
  int t = add_node();
  vector<pair<int, int>> node_nodes;
  for (int i = 0; i < n; ++i) {
    node_nodes.push_back({add_node(), add_node()});
    add_edge(node_nodes.back().first, node_nodes.back().second, 1, -cost[i]);
  }
  dfs(x, x, graph1, here1);
  for (auto& p : groups) {
    int tmp = add_node();
    add_edge(s, tmp, p.second, 0);
    for (int v : p.first) {
      add_edge(tmp, node_nodes[v].first, 1, 0);
    }
  }
  groups.clear();
  dfs(y, y, graph2, here2);
  for (auto& p : groups) {
    int tmp = add_node();
    add_edge(tmp, t, p.second, 0);
    for (int v : p.first) {
      add_edge(node_nodes[v].second, tmp, 1, 0);
    }
  }
  long long ans = 0;
  int f = 0;
  dist = vector<long long>(((int)graph.size()));
  in_queue = vector<bool>(((int)graph.size()));
  from = vector<pair<int, int>>(((int)graph.size()));
  while (true) {
    auto tmp = push_flow(s, t);
    if (!tmp.first) {
      break;
    }
    f += tmp.first;
    ans += tmp.second;
  }
  if (f != here1[x] || f != here2[y]) {
    cout << "-1\n";
    return;
  }
  cout << -ans << "\n";
}
int main() {
  cout << setprecision(15) << fixed;
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int test_count = 1;
  for (int test = 1; test <= test_count; ++test) {
    solve();
  }
}
