#include <bits/stdc++.h>
using namespace std;
const int List_N = 7 + 1000;
const int List_M = 7 + 2000000;
template <class T>
struct List {
  int e_n;
  int head[List_N];
  int next[List_M];
  T node[List_M];
  void init() {
    e_n = 0;
    memset(head, -1, sizeof(head));
  }
  void addedge(int fm, T aNode) {
    node[e_n] = aNode;
    next[e_n] = head[fm];
    head[fm] = e_n++;
  }
  T& operator[](int index) { return node[index]; }
};
struct Node1 {
  int to;
  Node1() {}
  Node1(int to) : to(to) {}
};
List<Node1> L1;
const int UF_N = 7 + 1000;
struct UF {
  int far[UF_N];
  void init() {
    for (int i = 0; i < UF_N; i++) far[i] = i;
  }
  int getf(int d) { return far[d] == d ? d : far[d] = getf(far[d]); }
  bool same(int a, int b) { return getf(a) == getf(b); }
  void comb(int a, int b) {
    if (same(a = getf(a), b = getf(b))) return;
    far[a] = b;
  }
} uf;
const int MAX_N = 7 + 1000;
const int MAX_W = 7 + 1000;
int w[MAX_N];
int v[MAX_N];
int f[MAX_W];
int main() {
  uf.init();
  int n, m, W;
  scanf("%d%d%d", &n, &m, &W);
  for (int i = 1; i <= n; i++) scanf("%d", &w[i]);
  for (int i = 1; i <= n; i++) scanf("%d", &v[i]);
  for (int i = 1; i <= m; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    uf.comb(a, b);
  }
  L1.init();
  for (int i = 1; i <= n; i++) uf.getf(i);
  for (int i = 1; i <= n; i++)
    if (uf.getf(i) == i)
      for (int j = 1; j <= n; j++)
        if (uf.getf(j) == i) L1.addedge(i, Node1(j));
  memset(f, 0, sizeof(f));
  for (int i = 1; i <= n; i++)
    if (uf.getf(i) == i) {
      for (int j = W; j >= 0; j--) {
        int sumw = 0;
        int sumv = 0;
        int d;
        for (int k = L1.head[i]; k >= 0; k = L1.next[k])
          if (uf.getf(d = L1[k].to) == i) {
            sumw += w[d];
            sumv += v[d];
            if (j >= w[d]) f[j] = max(f[j], f[j - w[d]] + v[d]);
          }
        if (j >= sumw) f[j] = max(f[j], f[j - sumw] + sumv);
      }
    }
  printf("%d", f[W]);
}
