#include <bits/stdc++.h>
using namespace std;
const long long INF = 1e9 + 7;
const int N = 1e3 + 10;
class UnionSet {
 public:
  int fa[N];
  void init() { memset((fa), (-1), sizeof(fa)); }
  int treesize(int x) { return -fa[Find(x)]; }
  int Find(int x) {
    int root = x;
    while (fa[root] >= 0) root = fa[root];
    while (x != root) {
      int tmp = fa[x];
      fa[x] = root;
      x = tmp;
    }
    return root;
  }
  void Union(int x, int y) {
    int px = Find(x);
    int py = Find(y);
    if (fa[px] > fa[py]) swap(px, py);
    int sz = fa[px] + fa[py];
    fa[py] = px;
    fa[px] = sz;
  }
} uf;
int w[N];
int b[N];
int w1[N];
int b1[N];
int dp[N];
vector<int> v[N];
int main() {
  int n, m, tot;
  cin >> n >> m >> tot;
  for (int i = 1; i <= n; i++) cin >> w[i];
  for (int i = 1; i <= n; i++) cin >> b[i];
  uf.init();
  memset((dp), (0x80), sizeof(dp));
  memset((w1), (0), sizeof(w1));
  memset((b1), (0), sizeof(b1));
  while (m--) {
    int x, y;
    cin >> x >> y;
    if (uf.Find(x) != uf.Find(y)) uf.Union(x, y);
  }
  for (int i = 1; i <= n; i++) {
    int p = uf.Find(i);
    w1[p] += w[i];
    b1[p] += b[i];
    v[p].push_back(i);
  }
  dp[0] = 0;
  for (int i = 1; i <= n; i++) {
    if (v[i].empty()) continue;
    int p = i;
    for (int j = tot; j >= 0; j--) {
      if (j >= w1[p]) dp[j] = max(dp[j], dp[j - w1[p]] + b1[p]);
      for (auto &k : v[i]) {
        if (j >= w[k]) dp[j] = max(dp[j], dp[j - w[k]] + b[k]);
      }
    }
  }
  int ans = 0;
  for (int i = 1; i <= tot; i++) ans = max(ans, dp[i]);
  cout << ans << endl;
  return 0;
}
