#include <bits/stdc++.h>
using namespace std;
const int NMax = 505;
int N, X, Y;
int A[NMax];
int F[NMax * 6], Cap[NMax * 6], Cost[NMax * 6];
vector<int> G[NMax * 3], Ed[NMax * 3];
vector<int> Tree1[NMax], Tree2[NMax];
queue<int> Q;
pair<int, int> E[NMax * 6];
int MinC, MaxFlow, Source, Dest, edge, Rev[6 * NMax];
priority_queue<pair<int, int>, vector<pair<int, int> >,
               greater<pair<int, int> > >
    S;
int Amount[2][NMax], Closest[2][NMax], Sum[2][NMax], Dist[NMax * 3],
    D[NMax * 3], realD[NMax * 3];
pair<int, int> TT[NMax * 3];
bool Demanded[2][NMax], InQ[NMax * 3];
void Read() {
  scanf("%d", &N);
  scanf("%d%d", &X, &Y);
  for (int i = 1; i <= N; i++) scanf("%d", &A[i]);
  for (int i = 1; i < N; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    Tree1[x].push_back(y);
    Tree1[y].push_back(x);
  }
  for (int i = 1; i < N; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    Tree2[x].push_back(y);
    Tree2[y].push_back(x);
  }
}
void readDemand() {
  int q;
  scanf("%d", &q);
  for (int i = 1; i <= q; i++) {
    int node, x;
    scanf("%d%d", &node, &x);
    Amount[0][node] = x;
    Demanded[0][node] = true;
  }
  scanf("%d", &q);
  for (int i = 1; i <= q; i++) {
    int node, x;
    scanf("%d%d", &node, &x);
    Amount[1][node] = x;
    Demanded[1][node] = true;
  }
}
void DFSTree1(int node, int father, int closest) {
  if (Demanded[0][node]) closest = node;
  Closest[0][node] = closest;
  for (int i = 0; i < Tree1[node].size(); i++) {
    int neighb = Tree1[node][i];
    if (neighb == father) continue;
    DFSTree1(neighb, node, closest);
    Sum[0][node] += Sum[0][neighb];
  }
  if (Demanded[0][node]) {
    int aux = Sum[0][node];
    Sum[0][node] = Amount[0][node];
    Amount[0][node] -= aux;
  }
}
void DFSTree2(int node, int father, int closest) {
  if (Demanded[1][node]) closest = node;
  Closest[1][node] = closest;
  for (int i = 0; i < Tree2[node].size(); i++) {
    int neighb = Tree2[node][i];
    if (neighb == father) continue;
    DFSTree2(neighb, node, closest);
    Sum[1][node] += Sum[1][neighb];
  }
  if (Demanded[1][node]) {
    int aux = Sum[1][node];
    Sum[1][node] = Amount[1][node];
    Amount[1][node] -= aux;
  }
}
void buildNetwork() {
  for (int i = 1; i <= N; i++) {
    if (Demanded[0][i]) {
      G[0].push_back(i);
      G[i].push_back(0);
      Ed[0].push_back(++edge);
      Cap[edge] = Amount[0][i];
      ;
      E[edge] = make_pair(0, i);
      Ed[i].push_back(++edge);
      Rev[edge] = edge - 1;
      Rev[edge - 1] = edge;
      E[edge] = make_pair(i, 0);
    }
    if (Demanded[1][i]) {
      G[i + N].push_back(2 * N + 1);
      G[2 * N + 1].push_back(i + N);
      Ed[i + N].push_back(++edge);
      Cap[edge] = Amount[1][i];
      E[edge] = make_pair(i + N, 2 * N + 1);
      Ed[2 * N + 1].push_back(++edge);
      E[edge] = make_pair(2 * N + 1, i + N);
      Rev[edge] = edge - 1;
      Rev[edge - 1] = edge;
    }
    G[Closest[0][i]].push_back(Closest[1][i] + N);
    G[Closest[1][i] + N].push_back(Closest[0][i]);
    Ed[Closest[0][i]].push_back(++edge);
    Cost[edge] = -A[i];
    Cap[edge] = 1;
    E[edge] = make_pair(Closest[0][i], Closest[1][i] + N);
    Ed[Closest[1][i] + N].push_back(++edge);
    E[edge] = make_pair(Closest[1][i] + N, Closest[0][i]);
    Cost[edge] = A[i];
    Rev[edge] = edge - 1;
    Rev[edge - 1] = edge;
  }
}
void bellmanFord(int node) {
  for (int i = 0; i <= Dest; i++) Dist[i] = 0x3f3f3f3f;
  Q.push(node);
  InQ[node] = 1;
  Dist[node] = 0;
  while (!Q.empty()) {
    int node = Q.front();
    InQ[node] = 0;
    Q.pop();
    for (int i = 0; i < G[node].size(); i++) {
      int neighb = G[node][i], ed = Ed[node][i], cost = Cost[ed], c = Cap[ed];
      if (c == 0) continue;
      if (Dist[neighb] > Dist[node] + cost) {
        Dist[neighb] = Dist[node] + cost;
        if (InQ[neighb] == 0) {
          InQ[neighb] = 1;
          Q.push(neighb);
        }
      }
    }
  }
}
bool dijsktra() {
  for (int i = 0; i <= Dest; i++) D[i] = 0x3f3f3f3f, TT[i] = make_pair(-1, -1);
  D[Source] = realD[Source] = 0;
  S.push(make_pair(0, Source));
  while (!S.empty()) {
    pair<int, int> p = S.top();
    int d = p.first, node = p.second;
    S.pop();
    if (D[node] < d) continue;
    for (int i = 0; i < G[node].size(); i++) {
      int neighb = G[node][i], ed = Ed[node][i], cap = Cap[ed], cost = Cost[ed];
      if (cap - F[ed] > 0) {
        int e = cost + Dist[node] - Dist[neighb];
        if (d + e < D[neighb]) {
          D[neighb] = d + e;
          S.push(make_pair(D[neighb], neighb));
          realD[neighb] = realD[node] + cost;
          TT[neighb] = make_pair(node, ed);
        }
      }
    }
  }
  return TT[Dest] != make_pair(-1, -1);
}
void Solve() {
  while (dijsktra()) {
    int Min = 0x3f3f3f3f;
    for (int i = Dest; i != Source; i = TT[i].first) {
      Min = min(Min, Cap[TT[i].second] - F[TT[i].second]);
    }
    MaxFlow += Min;
    MinC += Min * realD[Dest];
    for (int i = Dest; i != Source; i = TT[i].first) {
      F[TT[i].second] += Min;
      F[Rev[TT[i].second]] -= Min;
    }
    memcpy(Dist, realD, sizeof(Dist));
  }
  if (MaxFlow != max(Sum[0][X], Sum[1][Y]))
    printf("-1\n");
  else
    printf("%d\n", -MinC);
}
int main() {
  Read();
  Source = 0;
  Dest = 2 * N + 1;
  readDemand();
  DFSTree1(X, 0, X);
  DFSTree2(Y, 0, Y);
  for (int i = 1; i <= N; i++) {
    if (Amount[0][i] < 0 || Amount[1][i] < 0) {
      printf("-1\n");
      return 0;
    }
  }
  buildNetwork();
  bellmanFord(Source);
  Solve();
  return 0;
}
