import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.SortedSet;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * #
 *
 * @author pttrung
 */
public class A_Round_302_Div1 {

	public static long MOD = 1000000007;
	static long[][][] dp;

	public static void main(String[] args) throws FileNotFoundException {
		// PrintWriter out = new PrintWriter(new FileOutputStream(new File(
		// "output.txt")));
		PrintWriter out = new PrintWriter(System.out);
		Scanner in = new Scanner();

		int n = in.nextInt();
		int m = in.nextInt();
		int b = in.nextInt();
		MOD = in.nextInt();
		int[] data = new int[n];

		for (int i = 0; i < n; i++) {
			data[i] = in.nextInt();
		}

		dp = new long[2][n][b + 1];
		int cur = 1;
		for (int i = n - 1; i >= 0; i--) {
			if (i + 1 < n) {
				for (int j = 0; j <= b; j++) {
					dp[0][i][j] += dp[0][i + 1][j];
					dp[0][i][j] = mod(dp[0][i][j], MOD);
				}
			}
			if (data[i] <= b) {
				dp[0][i][data[i]]++;
				dp[0][i][data[i]] = mod(dp[0][i][data[i]], MOD);
			}

		}

		for (int i = 1; i < m; i++) {
			for (int j = n - 1; j >= 0; j--) {
				for (int k = b; k >= 0; k--) {
					dp[cur][j][k] = 0;
					if (j + 1 < n) {
						dp[cur][j][k] += dp[cur][j + 1][k];
						mod(dp[cur][j][k], MOD);
					}
					if (k + data[j] <= b) {
						dp[cur][j][k + data[j]] += dp[1 - cur][j][k];
						dp[cur][j][k + data[j]] = mod(dp[cur][j][k + data[j]],
								MOD);
					}
				}
			}
			cur = 1 - cur;
		}
		long result = 0;
		for (int i = 0; i <= b; i++) {
			result += dp[1 - cur][0][i];
			result = mod(result, MOD);
		}
		out.println(result);
		out.close();
	}

	static long mod(long a, long mod) {

		while (a >= mod) {
			a -= mod;
		}
		return a;
	}

	public static int[] KMP(String val) {
		int i = 0;
		int j = -1;
		int[] result = new int[val.length() + 1];
		result[0] = -1;
		while (i < val.length()) {
			while (j >= 0 && val.charAt(j) != val.charAt(i)) {
				j = result[j];
			}
			j++;
			i++;
			result[i] = j;
		}
		return result;

	}

	public static boolean nextPer(int[] data) {
		int i = data.length - 1;
		while (i > 0 && data[i] < data[i - 1]) {
			i--;
		}
		if (i == 0) {
			return false;
		}
		int j = data.length - 1;
		while (data[j] < data[i - 1]) {
			j--;
		}
		int temp = data[i - 1];
		data[i - 1] = data[j];
		data[j] = temp;
		Arrays.sort(data, i, data.length);
		return true;
	}

	public static int digit(long n) {
		int result = 0;
		while (n > 0) {
			n /= 10;
			result++;
		}
		return result;
	}

	public static double dist(long a, long b, long x, long y) {
		double val = (b - a) * (b - a) + (x - y) * (x - y);
		val = Math.sqrt(val);
		double other = x * x + a * a;
		other = Math.sqrt(other);
		return val + other;

	}

	public static class Point implements Comparable<Point> {

		int x, y;

		public Point(int start, int end) {
			this.x = start;
			this.y = end;
		}

		@Override
		public int hashCode() {
			int hash = 5;
			hash = 47 * hash + this.x;
			hash = 47 * hash + this.y;
			return hash;
		}

		@Override
		public boolean equals(Object obj) {
			if (obj == null) {
				return false;
			}
			if (getClass() != obj.getClass()) {
				return false;
			}
			final Point other = (Point) obj;
			if (this.x != other.x) {
				return false;
			}
			if (this.y != other.y) {
				return false;
			}
			return true;
		}

		@Override
		public int compareTo(Point o) {
			return x - o.x;
		}
	}

	public static class FT {

		long[] data;

		FT(int n) {
			data = new long[n];
		}

		public void update(int index, long value) {
			while (index < data.length) {
				data[index] += value;
				index += (index & (-index));
			}
		}

		public long get(int index) {
			long result = 0;
			while (index > 0) {
				result += data[index];
				index -= (index & (-index));
			}
			return result;

		}
	}

	public static long gcd(long a, long b) {
		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}

	public static long pow(long a, long b) {
		if (b == 0) {
			return 1;
		}
		if (b == 1) {
			return a;
		}
		long val = pow(a, b / 2);
		if (b % 2 == 0) {
			return val * val % MOD;
		} else {
			return val * (val * a % MOD) % MOD;

		}
	}

	static class Scanner {

		BufferedReader br;
		StringTokenizer st;

		public Scanner() throws FileNotFoundException {
			// System.setOut(new PrintStream(new
			// BufferedOutputStream(System.out), true));
			br = new BufferedReader(new InputStreamReader(System.in));
			// br = new BufferedReader(new InputStreamReader(new
			// FileInputStream(new File("input.txt"))));
		}

		public String next() {

			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					throw new RuntimeException();
				}
			}
			return st.nextToken();
		}

		public long nextLong() {
			return Long.parseLong(next());
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

		public double nextDouble() {
			return Double.parseDouble(next());
		}

		public String nextLine() {
			st = null;
			try {
				return br.readLine();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}

		public boolean endLine() {
			try {
				String next = br.readLine();
				while (next != null && next.trim().isEmpty()) {
					next = br.readLine();
				}
				if (next == null) {
					return true;
				}
				st = new StringTokenizer(next);
				return st.hasMoreTokens();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}
	}
}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.SortedSet;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * #
 *
 * @author pttrung
 */
public class A_Round_302_Div1 {

	public static long MOD = 1000000007;
	static long[][] dp;
	static int[][] other;

	public static void main(String[] args) throws FileNotFoundException {
		// PrintWriter out = new PrintWriter(new FileOutputStream(new File(
		// "output.txt")));
		PrintWriter out = new PrintWriter(System.out);
		Scanner in = new Scanner();

		int n = in.nextInt();
		int m = in.nextInt();
		int b = in.nextInt();
		MOD = in.nextInt();
		int[] data = new int[n];

		for (int i = 0; i < n; i++) {
			data[i] = in.nextInt();
		}
		int[][] check = new int[m + 1][b + 1];
		int index = 0;

		dp = new long[m ][b + 1];
		for(long[]a : dp){
			Arrays.fill(a,-1);
		}
		out.println(cal(0,0,m,b,data));

		out.close();
	}

	static long cal(int index, int bug, int m,int b, int[]data){
		if(index == m){
			return 1;
		}
		if(dp[index][bug] != -1){
			return dp[index][bug];
		}
		long result = 0;
		for(int i = 0; i < data.length; i++){
			if(bug + data[i] <= b){
				result += cal(index + 1, bug + data[i],m,b,data);
				result %= MOD;
			}
		}
		return dp[index][bug] = result;
	}

	public static int[] KMP(String val) {
		int i = 0;
		int j = -1;
		int[] result = new int[val.length() + 1];
		result[0] = -1;
		while (i < val.length()) {
			while (j >= 0 && val.charAt(j) != val.charAt(i)) {
				j = result[j];
			}
			j++;
			i++;
			result[i] = j;
		}
		return result;

	}

	public static boolean nextPer(int[] data) {
		int i = data.length - 1;
		while (i > 0 && data[i] < data[i - 1]) {
			i--;
		}
		if (i == 0) {
			return false;
		}
		int j = data.length - 1;
		while (data[j] < data[i - 1]) {
			j--;
		}
		int temp = data[i - 1];
		data[i - 1] = data[j];
		data[j] = temp;
		Arrays.sort(data, i, data.length);
		return true;
	}

	public static int digit(long n) {
		int result = 0;
		while (n > 0) {
			n /= 10;
			result++;
		}
		return result;
	}

	public static double dist(long a, long b, long x, long y) {
		double val = (b - a) * (b - a) + (x - y) * (x - y);
		val = Math.sqrt(val);
		double other = x * x + a * a;
		other = Math.sqrt(other);
		return val + other;

	}

	public static class Point implements Comparable<Point> {

		int x, y;

		public Point(int start, int end) {
			this.x = start;
			this.y = end;
		}

		@Override
		public int hashCode() {
			int hash = 5;
			hash = 47 * hash + this.x;
			hash = 47 * hash + this.y;
			return hash;
		}

		@Override
		public boolean equals(Object obj) {
			if (obj == null) {
				return false;
			}
			if (getClass() != obj.getClass()) {
				return false;
			}
			final Point other = (Point) obj;
			if (this.x != other.x) {
				return false;
			}
			if (this.y != other.y) {
				return false;
			}
			return true;
		}

		@Override
		public int compareTo(Point o) {
			return x - o.x;
		}
	}

	public static class FT {

		long[] data;

		FT(int n) {
			data = new long[n];
		}

		public void update(int index, long value) {
			while (index < data.length) {
				data[index] += value;
				index += (index & (-index));
			}
		}

		public long get(int index) {
			long result = 0;
			while (index > 0) {
				result += data[index];
				index -= (index & (-index));
			}
			return result;

		}
	}

	public static long gcd(long a, long b) {
		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}

	public static long pow(long a, long b) {
		if (b == 0) {
			return 1;
		}
		if (b == 1) {
			return a;
		}
		long val = pow(a, b / 2);
		if (b % 2 == 0) {
			return val * val % MOD;
		} else {
			return val * (val * a % MOD) % MOD;

		}
	}

	static class Scanner {

		BufferedReader br;
		StringTokenizer st;

		public Scanner() throws FileNotFoundException {
			// System.setOut(new PrintStream(new
			// BufferedOutputStream(System.out), true));
			br = new BufferedReader(new InputStreamReader(System.in));
			// br = new BufferedReader(new InputStreamReader(new
			// FileInputStream(new File("input.txt"))));
		}

		public String next() {

			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					throw new RuntimeException();
				}
			}
			return st.nextToken();
		}

		public long nextLong() {
			return Long.parseLong(next());
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

		public double nextDouble() {
			return Double.parseDouble(next());
		}

		public String nextLine() {
			st = null;
			try {
				return br.readLine();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}

		public boolean endLine() {
			try {
				String next = br.readLine();
				while (next != null && next.trim().isEmpty()) {
					next = br.readLine();
				}
				if (next == null) {
					return true;
				}
				st = new StringTokenizer(next);
				return st.hasMoreTokens();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}
	}
}


#pragma GCC optimize("O3")

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mset(m,v) memset(m,v,sizeof(m))
#define pr(a,s) printf("Case #%lld: %lld\n",a,s)
#define mod 1000000007
#define mp make_pair
#define all(a)                a.begin(),a.end()
#define pb push_back
#define scan(a) scanf("%d",&a)
#define scanl(a) scanf("%lld",&a)
#define se second
#define fi first
#define pi 3.14159265358979323
#define pii pair<ll,ll>
#define int ll

const int inf = 2e9;
const int MAXM = 1e5+5;
const int MAXN = 1e6+4;

int ww[MAXM],b[MAXM],su=0,bb=0,maxm = 0,CC=0;
set<int> s;
vector<int> v[MAXM];
bool visit[MAXM];
vector<int> vc[MAXM];
int dp[1001][1001];

void DFS(int x)
{
	su += ww[x];
	bb += b[x];
	vc[CC].pb(x);
	visit[x]=1;
	for(auto it : v[x]){
		if(visit[it])	continue;
		DFS(it);
	}
}

int solve(int c,int w)
{
	if(w<0)	return -inf;
	if(c==0 or w==0)	return 0;
	if(dp[c][w]!=-1)	return dp[c][w];
	int ret = 0;
	for(int i=0;i<vc[c].size();i++){
		int p = vc[c][i];
		// cout<<p<<endl;
		ret = max(ret, b[p]+solve(c-1,w-ww[p]));
	}
	ret = max(ret,solve(c-1,w));
	dp[c][w] = ret;
	return ret;
}

int32_t main()
{
	mset(dp,-1);
	int n,m,w,i,j,k;
	scanl(n);scanl(m);scanl(w);
	for(i=1;i<=n;i++){
		scanl(ww[i]);
	}
	for(i=1;i<=n;i++){
		scanl(b[i]);
	}
	for(i=1;i<=m;i++){
		int x,y;
		scanl(x);scanl(y);
		v[x].pb(y);
		v[y].pb(x);
	}
	CC = 0;
	for(i=1;i<=n;i++){
		if(!visit[i]){
			CC++;
			su = 0;
			bb = 0;
			DFS(i);
			if(w>=su)
				s.insert(bb);
		}
	}
	// Time for some 2-D dp
	cout<<max(solve(CC,w),(*s.rbegin()))<<endl;
	return 0;
}


#pragma GCC optimize("O3")

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mset(m,v) memset(m,v,sizeof(m))
#define pr(a,s) printf("Case #%lld: %lld\n",a,s)
#define mod 1000000007
#define mp make_pair
#define all(a)                a.begin(),a.end()
#define pb push_back
#define scan(a) scanf("%d",&a)
#define scanl(a) scanf("%lld",&a)
#define se second
#define fi first
#define pi 3.14159265358979323
#define pii pair<ll,ll>
#define int ll

const int inf = 2e17;
const int MAXM = 1e5+5;
const int MAXN = 1e6+4;

int ww[MAXM],b[MAXM],su[MAXM],bb[MAXM],maxm = 0,CC=0;
set<int> s;
vector<int> v[MAXM];
bool visit[MAXM];
vector<int> vc[MAXM];
int dp[1001][1001];

void DFS(int x)
{
	su[CC] += ww[x];
	bb[CC] += b[x];
	vc[CC].pb(x);
	visit[x]=1;
	for(auto it : v[x]){
		if(visit[it])	continue;
		DFS(it);
	}
}

int solve(int c,int w)
{
	// cout<<c<<" "<<w<<endl;
	if(w<0)	return -inf;
	if(c==0 or w==0)	return 0;
	ll ret = 0;
	ret = max(ret,solve(c-1,w));
	for(int i=0;i<vc[c].size();i++){
		int p = vc[c][i];
		if(w>=ww[p])
			ret = max(ret, b[p]+solve(c-1,w-ww[p]));
	}
	if(w>=su[c]){
		ret = max(ret, bb[c]+solve(c-1,w-su[c]));
	}
	return ret;
}

int32_t main()
{
	mset(dp,-1);
	int n,m,w,i,j,k;
	scanl(n);scanl(m);scanl(w);
	for(i=1;i<=n;i++){
		scanl(ww[i]);
	}
	for(i=1;i<=n;i++){
		scanl(b[i]);
	}
	for(i=1;i<=m;i++){
		int x,y;
		scanl(x);scanl(y);
		v[x].pb(y);
		v[y].pb(x);
	}
	CC = 0;
	for(i=1;i<=n;i++){
		if(!visit[i]){
			CC++;
			DFS(i);
		}
	}
	// Time for some 2-D dp
	cout<<solve(CC,w)<<endl;
	return 0;
}


#pragma GCC optimize("O3")

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mset(m,v) memset(m,v,sizeof(m))
#define pr(a,s) printf("Case #%lld: %lld\n",a,s)
#define mod 1000000007
#define mp make_pair
#define all(a)                a.begin(),a.end()
#define pb push_back
#define scan(a) scanf("%d",&a)
#define scanl(a) scanf("%lld",&a)
#define se second
#define fi first
#define pi 3.14159265358979323
#define pii pair<ll,ll>

const int inf = 2e9;
const int MAXM = 1e5+5;
const int MAXN = 1e6+4;

int ww[MAXM],b[MAXM],su=0,bb=0,maxm = 0,CC=0;
set<int> s;
vector<int> v[MAXM];
bool visit[MAXM];
vector<int> vc[MAXM];
int dp[1001][1001];

void DFS(int x)
{
	su += ww[x];
	bb += b[x];
	vc[CC].pb(x);
	visit[x]=1;
	for(auto it : v[x]){
		if(visit[it])	continue;
		DFS(it);
	}
}

int solve(int c,int w)
{
	if(w<0)	return -inf;
	if(c==0 or w==0)	return 0;
	if(dp[c][w]!=-1)	return dp[c][w];
	int ret = 0;
	for(int i=0;i<vc[c].size();i++){
		int p = vc[c][i];
		// cout<<p<<endl;
		ret = max(ret, b[p]+solve(c-1,w-ww[p]));
	}
	ret = max(ret,solve(c-1,w));
	dp[c][w] = ret;
	return ret;
}

int main()
{
	mset(dp,-1);
	int n,m,w,i,j,k;
	scan(n);scan(m);scan(w);
	for(i=1;i<=n;i++){
		scan(ww[i]);
	}
	for(i=1;i<=n;i++){
		scan(b[i]);
	}
	for(i=1;i<=m;i++){
		int x,y;
		scan(x);scan(y);
		v[x].pb(y);
		v[y].pb(x);
	}
	CC = 0;
	for(i=1;i<=n;i++){
		if(!visit[i]){
			CC++;
			su = 0;
			bb = 0;
			DFS(i);
			if(w>=su)
				s.insert(bb);
		}
	}
	// Time for some 2-D dp
	cout<<max(solve(CC,w),(*s.rbegin()))<<endl;
	return 0;
}


#include <iostream>
#include <algorithm>
#include <bitset>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <iomanip>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <cstdlib>
using namespace std;

//ifstream cin ("f.in");
//ofstream cout ("f.out");

int N, M, Wmax, sol;
int W[1002], B[1002], GrW[1002], GrB[1002], Belong[1002];
int D[1002];
bool viz[1002];
bitset <1001> Conf[1001];
vector <int> Graph[1002], FinW, FinB;
vector <vector<int> > Gr;

void DF(int x, int k);

int main()
{
    cin >> N >> M >> Wmax;
    for (int i = 1; i <= N; ++i)
        cin >> W[i];
    for (int i = 1; i <= N; ++i)
        cin >> B[i];
    for (int x, y; M; --M)
    {
        cin >> x >> y;
        Graph[x].push_back(y);
        Graph[y].push_back(x);
    }
    for (int i = 1; i <= N; ++i)
        if (viz[i] == 0)
        {
            Gr.push_back(vector<int>());
            DF(i, Gr.size()-1);
        }

    for (int i = 1; i <= Wmax; ++i)
        D[i] = -1;

    for (int i = 0; i < Gr.size(); ++i)
    {
        for (const int& j : Gr[i])
            for (int w = Wmax - W[j]; w >= 0 ; --w)
                if (D[w] >= 0 && Conf[w][i] == 0 && D[w+W[j]] < D[w] + B[j])
                    D[w+W[j]] = D[w] + B[j],
                    Conf[w+W[j]][i] = 1;

        for (int w = Wmax - GrW[i]; w >= 0 ; --w)
            if (D[w] >= 0 && Conf[w][i] == 0 && D[w+GrW[i]] < D[w] + GrB[i])
                Conf[w+GrW[i]][i] = 1,
                D[w+GrW[i]] = D[w] + GrB[i];
    }

    for (int ax = 0; ax <= Wmax; ++ax)
        sol = max(sol, D[ax]);

    cout << sol;

}

void DF(int x, int k)
{
    GrW[k] += W[x];
    GrB[k] += B[x];
    viz[x] = 1;
    Gr[k].push_back(x);
    for (const int& y : Graph[x])
        if (viz[y] == 0)
            DF(y, k);
};


#include <algorithm>
#include <bitset>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <iomanip>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <cstdlib>
using namespace std;

#ifndef ONLINE_JUDGE

#include <fstream>
ifstream cin ("f.in");
ofstream cout ("f.out");

#else

#include <iostream>

#endif // ONLINE_JUDGE

const int Nmax = 2004;

int N, M, Wmax, sol;
int W[Nmax], B[Nmax], GrW[Nmax], GrB[Nmax], Belong[Nmax];
int D[Nmax][Nmax];
bool viz[Nmax];
vector <int> Graph[Nmax], FinW, FinB;
vector <vector<int> > Gr;

void DF(int x, int k);

int main()
{
    cin >> N >> M >> Wmax;
    for (int i = 1; i <= N; ++i)
        cin >> W[i];
    for (int i = 1; i <= N; ++i)
        cin >> B[i];
    for (int x, y; M; --M)
    {
        cin >> x >> y;
        Graph[x].push_back(y);
        Graph[y].push_back(x);
    }
    Gr.push_back(vector<int>());
    for (int i = 1; i <= N; ++i)
        if (viz[i] == 0)
        {
            Gr.push_back(vector<int>());
            DF(i, Gr.size()-1);
        }

    memset(D, -1, sizeof(D));
    for (int i = 0; i < Gr.size(); ++i)
        D[i][0] = 0;
    for (int i = 1; i < Gr.size(); ++i)
    {
        for (const int& j : Gr[i])
            for (int w = Wmax - W[j]; w >= 0 ; --w)
                if (D[i-1][w] >= 0 && D[i][w+W[j]] < D[i-1][w] + B[j])
                    D[i][w+W[j]] = D[i-1][w] + B[j], sol = max(sol, D[i][w+W[j]]);

        for (int w = Wmax - GrW[i]; w >= 0 ; --w)
            if (D[i-1][w] >= 0 && D[i][w+GrW[i]] < D[i-1][w] + GrB[i])
                D[i][w+GrW[i]] = D[i-1][w] + GrB[i], sol = max(sol, D[i][w+GrW[i]]);
    }
  //  for (int i = 0; i < Gr.size(); ++i, cout << '\n')
 //       for (int w = 0; w <= Wmax; ++w)
//            cout << D[i][w] << ' ';
    cout << sol;

}

void DF(int x, int k)
{
    GrW[k] += W[x];
    GrB[k] += B[x];
    viz[x] = 1;
    Gr[k].push_back(x);
    for (const int& y : Graph[x])
        if (viz[y] == 0)
            DF(y, k);
};


#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <iomanip>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <cstdlib>
using namespace std;

//ifstream cin ("f.in");
//ofstream cout ("f.out");

int N, M, Wmax, sol;
int W[1002], B[1002], GrW[1002], GrB[1002], Belong[1002];
int D[1002];
bool viz[1002];
vector <int> Graph[1002], FinW, FinB;
vector <vector<int> > Gr;

void DF(int x, int k);

int main()
{
    cin >> N >> M >> Wmax;
    for (int i = 1; i <= N; ++i)
        cin >> W[i];
    for (int i = 1; i <= N; ++i)
        cin >> B[i];
    for (int x, y; M; --M)
    {
        cin >> x >> y;
        Graph[x].push_back(y);
        Graph[y].push_back(x);
    }
    for (int i = 1; i <= N; ++i)
        if (viz[i] == 0)
        {
            Gr.push_back(vector<int>());
            DF(i, Gr.size()-1);
        }
    for (int i = 0; i < Gr.size(); ++i)
        for (const int j : Gr[i])
            Belong[j] = i;

    for (int i = 0; i < Gr.size(); ++i)
        if (Gr[i].size() > 1)
            FinW.push_back(GrW[i]),
            FinB.push_back(GrB[i]);
    for (int i = 0; i < Gr.size(); ++i)
    {
        int a = 0, b = 999999, ind;
        for (const int j : Gr[i])
            if (1LL * a * W[j] < 1LL * b * B[j])
                a = B[j], b = W[j], ind = j;

        FinB.push_back(B[ind]);
        FinW.push_back(W[ind]);

    }

    N = FinW.size();
    for (int i = 1; i <= Wmax; ++i)
        D[i] = -1;
    for (int i = 0; i < N; ++i)
        for (int j = Wmax-FinW[i]; j >= 0; --j)
            if (D[j] >= 0 && D[j+FinW[i]] < D[j]+FinB[i])
                D[j+FinW[i]] = D[j] + FinB[i], sol = max(D[j+FinW[i]], sol);
    cout << sol;

}

void DF(int x, int k)
{
    GrW[k] += W[x];
    GrB[k] += B[x];
    viz[x] = 1;
    Gr[k].push_back(x);
    for (const int& y : Graph[x])
        if (viz[y] == 0)
            DF(y, k);
};


#include <algorithm>
#include <bitset>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <iomanip>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <cstdlib>
using namespace std;

#ifndef ONLINE_JUDGE

#include <fstream>
ifstream cin ("f.in");
ofstream cout ("f.out");

#else

#include <iostream>

#endif // ONLINE_JUDGE

#define HosTemp pair<int,int>
#define w first
#define b second

const int Nmax = 1010;

int N, M, Wmax;
int W[Nmax], B[Nmax];
int D[Nmax];
bool viz[Nmax];
vector <int> Graph[Nmax];

void DF(int x, vector<HosTemp>& hoses, int& sumw, int& sumb);

int main()
{
    cin >> N >> M >> Wmax;
    for (int i = 1; i <= N; ++i)
        cin >> W[i];
    for (int i = 1; i <= N; ++i)
        cin >> B[i];
    for (int x, y; M; --M)
    {
        cin >> x >> y;
        Graph[x].push_back(y);
        Graph[y].push_back(x);
    }
    for (int x = 1; x <= N; ++x)
        if (viz[x] == 0)
        {
            vector <HosTemp> Gr;
            int sumw = 0, sumb = 0;
            DF(x, Gr, sumw, sumb);
            if (Gr.size() > 1)
                Gr.push_back({sumw, sumb});

            for (int w = Wmax; w >= 0; --w)
                for (const auto& hoe : Gr)
                    if (w >= hoe.w)
                        D[w] = max(D[w], D[w - hoe.w] + hoe.b);
        }

    cout << D[Wmax];
}

void DF(int x, vector<HosTemp>& hoses, int& sumw, int& sumb)
{
    sumw += W[x], sumb += B[x];
    hoses.push_back({W[x], B[x]});
    viz[x] = 1;
    for (const int& y : Graph[x])
        if (viz[y] == 0)
            DF(y, hoses, sumw, sumb);
};


#include <algorithm>
#include <bitset>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <iomanip>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <cstdlib>
using namespace std;

#ifndef ONLINE_JUDGE

#include <fstream>
ifstream cin ("f.in");
ofstream cout ("f.out");

#else

#include <iostream>

#endif // ONLINE_JUDGE

const int Nmax = 2004;

int N, M, Wmax, sol;
int W[Nmax], B[Nmax], GrW[Nmax], GrB[Nmax], Belong[Nmax];
int D[Nmax];
bool viz[Nmax];
bitset <Nmax> Conf[Nmax];
vector <int> Graph[Nmax], FinW, FinB;
vector <vector<int> > Gr;

void DF(int x, int k);

int main()
{
    cin >> N >> M >> Wmax;
    for (int i = 1; i <= N; ++i)
        cin >> W[i];
    for (int i = 1; i <= N; ++i)
        cin >> B[i];
    for (int x, y; M; --M)
    {
        cin >> x >> y;
        Graph[x].push_back(y);
        Graph[y].push_back(x);
    }
    for (int i = 1; i <= N; ++i)
        if (viz[i] == 0)
        {
            Gr.push_back(vector<int>());
            DF(i, Gr.size()-1);
        }

    for (int i = 1; i <= Wmax; ++i)
        D[i] = -1;

    for (int i = 0; i < Gr.size(); ++i)
    {
        for (const int& j : Gr[i])
            for (int w = Wmax - W[j]; w >= 0 ; --w)
                if (D[w] >= 0 && Conf[w][i] == 0 && D[w+W[j]] < D[w] + B[j])
                    D[w+W[j]] = D[w] + B[j],
                    Conf[w+W[j]][i] = 1;

        for (int w = Wmax - GrW[i]; w >= 0 ; --w)
            if (D[w] >= 0 && Conf[w][i] == 0 && D[w+GrW[i]] < D[w] + GrB[i])
                Conf[w+GrW[i]][i] = 1,
                D[w+GrW[i]] = D[w] + GrB[i];
    }

    for (int ax = 0; ax <= Wmax; ++ax)
        sol = max(sol, D[ax]);

    cout << sol;

}

void DF(int x, int k)
{
    GrW[k] += W[x];
    GrB[k] += B[x];
    viz[x] = 1;
    Gr[k].push_back(x);
    for (const int& y : Graph[x])
        if (viz[y] == 0)
            DF(y, k);
};


#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>

#define sd(n) scanf("%d",&n) == 0
#define sl(n) scanf("%I64d",&n) == 0
#define ss(n) scanf("%s",n) == 0
#define sc(n) scanf(" %c",&n) == 0

#define pd(x) printf("%d", x)
#define ps(x) printf("%s", x)
#define pl(x) printf("%I64d", x)

#define rep(i, begin, end) for (decltype(begin) i = begin; i < end; i++)
#define revrep(i, begin, end) for (decltype(begin) i = end - 1; i >= begin; i--)
#define all(a) a.begin(), a.end()

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<long> vl;
typedef pair<int, int> pii;

long weights[2000];
long beau[2000];

vi friends[1000];
vector<pii> groups[1000];
int gi = 0;
int visited[1000] = {};

long dp[1001];
long newdp[1001] = {};
long emptydp[1001] = {};

long gb = 0, gw = 0;

void dfs(int i) {
	if (visited[i]) return;
	visited[i] = 1;
	gb += beau[i];
	gw += weights[i];

	groups[gi].push_back({ beau[i], weights[i] });

	for (int f : friends[i]) dfs(f);
}

long max2(long a, long b) {
	if (a > b) return a;
	return b;
}

int main() {
	int n, m, w;
	sd(n); sd(m); sd(w);

	rep(i, 0, n) sd(weights[i]);
	rep(i, 0, n) sd(beau[i]);

	int a, b;
	rep(i, 0, m) {
		sd(a); sd(b); a--; b--;
		friends[a].push_back(b);
		friends[b].push_back(a);
	}

	rep(i, 0, n) {
		dfs(i);

		if (groups[gi].size() > 1)
			groups[gi].push_back({ gb, gw });

		if (groups[gi].size() > 0) {
			gi++;
			gb = gw = 0;
		}
	}

	int best = 0;
	rep(i, 0, gi) {
		rep(j, 1, w + 1) {
			newdp[j] = dp[j];
			for (pii g : groups[i]) {
				if (g.second > j) {
					newdp[j] = max(newdp[j], newdp[j - 1]);
				}
				else {
					newdp[j] = max(newdp[j], dp[j - g.second] + g.first);
					if (newdp[j] > best) best = newdp[j];
				}
			}
		}
		memcpy(dp, newdp, (w + 1) * sizeof(long));
		memset(newdp, 0, (w + 1) * sizeof(long));
	}

	pd(best);
}


#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>

#define sd(n) scanf("%d",&n) == 0
#define sl(n) scanf("%I64d",&n) == 0
#define ss(n) scanf("%s",n) == 0
#define sc(n) scanf(" %c",&n) == 0

#define pd(x) printf("%d", x)
#define ps(x) printf("%s", x)
#define pl(x) printf("%I64d", x)

#define rep(i, begin, end) for (decltype(begin) i = begin; i < end; i++)
#define revrep(i, begin, end) for (decltype(begin) i = end - 1; i >= begin; i--)
#define all(a) a.begin(), a.end()

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<long> vl;
typedef pair<int, int> pii;

long weights[2000];
long beau[2000];

vi friends[1000];
vi groups[1000];
int gi = 0;
int visited[1000] = {};

long dp[1001];
long newdp[1001] = {};
long emptydp[1001] = {};

long gb = 0, gw = 0;

void dfs(int i) {
	if (visited[i]) return;
	visited[i] = 1;
	gb += beau[i];
	gw += weights[i];

	groups[gi].push_back(i);

	for (int f : friends[i]) dfs(f);
}

long max2(long a, long b) {
	if (a > b) return a;
	return b;
}

int main() {
	int n, m, w;
	sd(n); sd(m); sd(w);

	rep(i, 0, n) sd(weights[i]);
	rep(i, 0, n) sd(beau[i]);

	int a, b;
	rep(i, 0, m) {
		sd(a); sd(b); a--; b--;
		friends[a].push_back(b);
		friends[b].push_back(a);
	}
	int nn = n;
	rep(i, 0, nn) {
		dfs(i);

		if (groups[gi].size() > 1) {
			beau[n] = gb;
			weights[n] = gw;
			groups[gi].push_back(n);
			n++;
		}

		if (groups[gi].size() > 0) {
			gi++;
			gb = gw = 0;
		}
	}

	int best = 0;
	rep(i, 0, gi) {
		rep(j, 1, w + 1) {
			for (int g : groups[i]) {
				if (weights[g] > j) {
					newdp[j] = max2(max2(newdp[j], dp[j]), newdp[j - 1]);
				}
				else {
					newdp[j] = max2(max2(newdp[j], dp[j]), dp[j - weights[g]] + beau[g]);
					if (newdp[j] > best) best = newdp[j];
				}
			}
		}
		memcpy(dp, newdp, (w + 1) * sizeof(long));
		memset(newdp, 0, (w + 1) * sizeof(long));
	}

	pd(best);
}


#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>

#define sd(n) scanf("%d",&n) == 0
#define sl(n) scanf("%I64d",&n) == 0
#define ss(n) scanf("%s",n) == 0
#define sc(n) scanf(" %c",&n) == 0

#define pd(x) printf("%d", x)
#define ps(x) printf("%s", x)
#define pl(x) printf("%I64d", x)

#define rep(i, begin, end) for (decltype(begin) i = begin; i < end; i++)
#define revrep(i, begin, end) for (decltype(begin) i = end - 1; i >= begin; i--)
#define all(a) a.begin(), a.end()

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<long> vl;
typedef pair<int, int> pii;

long weights[2000];
long beau[2000];

vi friends[1000];
vi groups[1000];
int gi = 0;
int visited[1000] = {};

long dp[1001];
long newdp[1001] = {};
long emptydp[1001] = {};

long gb = 0, gw = 0;

void dfs(int i) {
	if (visited[i]) return;
	visited[i] = 1;
	gb += beau[i];
	gw += weights[i];

	groups[gi].push_back(i);

	for (int f : friends[i]) dfs(f);
}

long max2(long a, long b) {
	if (a > b) return a;
	return b;
}

int main() {
	int n, m, w;
	sd(n); sd(m); sd(w);

	rep(i, 0, n) sd(weights[i]);
	rep(i, 0, n) sd(beau[i]);

	int a, b;
	rep(i, 0, m) {
		sd(a); sd(b); a--; b--;
		friends[a].push_back(b);
		friends[b].push_back(a);
	}
	int nn = n;
	rep(i, 0, nn) {
		dfs(i);

		if (groups[gi].size() > 1) {
			beau[n] = gb;
			weights[n] = gw;
			groups[gi].push_back(n);
			n++;
		}

		if (groups[gi].size() > 0) {
			gi++;
			gb = gw = 0;
		}
	}

	int best = 0;
	rep(i, 0, gi) {
		rep(j, 1, w + 1) {
			newdp[j] = dp[j];
			for (int g : groups[i]) {
				if (weights[g] > j) {
					newdp[j] = max(newdp[j], newdp[j - 1]);
				}
				else {
					newdp[j] = max(newdp[j], dp[j - weights[g]] + beau[g]);
					if (newdp[j] > best) best = newdp[j];
				}
			}
		}
		memcpy(dp, newdp, (w + 1) * sizeof(long));
		memset(newdp, 0, (w + 1) * sizeof(long));
	}

	pd(best);
}


#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>

#define sd(n) scanf("%d",&n) == 0
#define sl(n) scanf("%I64d",&n) == 0
#define ss(n) scanf("%s",n) == 0
#define sc(n) scanf(" %c",&n) == 0

#define pd(x) printf("%d", x)
#define ps(x) printf("%s", x)
#define pl(x) printf("%I64d", x)

#define rep(i, begin, end) for (decltype(begin) i = begin; i < end; i++)
#define revrep(i, begin, end) for (decltype(begin) i = end - 1; i >= begin; i--)
#define all(a) a.begin(), a.end()

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<long> vl;
typedef pair<int, int> pii;

long weights[2000];
long beau[2000];

vi friends[1000];
vi groups[1000];
int gi = 0;
int visited[1000] = {};

long dp[1001];
long newdp[1001] = {};
long emptydp[1001] = {};

long gb = 0, gw = 0;

void dfs(int i) {
	if (visited[i]) return;
	visited[i] = 1;
	gb += beau[i];
	gw += weights[i];

	groups[gi].push_back(i);

	for (int f : friends[i]) dfs(f);
}

long max2(long a, long b) {
	if (a > b) return a;
	return b;
}

int main() {
	int n, m, w;
	sd(n); sd(m); sd(w);

	rep(i, 0, n) sd(weights[i]);
	rep(i, 0, n) sd(beau[i]);

	int a, b;
	rep(i, 0, m) {
		sd(a); sd(b);
		friends[a].push_back(b);
		friends[b].push_back(a);
	}
	int nn = n;
	rep(i, 0, nn) {
		dfs(i);

		if (groups[gi].size() > 1) {
			beau[n] = gb;
			weights[n] = gw;
			groups[gi].push_back(n);
		}

		gb = gw = 0;

		n++;
		gi++;
	}

	int best = 0;
	rep(i, 0, gi) {
		rep(j, 1, w + 1) {
			for (int g : groups[i]) {
				if (weights[g] < j) {
					newdp[j] = max2(newdp[j], newdp[j - 1]);
				}
				else {
					newdp[j] = max2(newdp[j], dp[j - weights[g]] + beau[g]);
					if (newdp[j] > best) best = newdp[j];
				}
			}

			memcpy(dp, newdp, w + 1);
			memcpy(newdp, emptydp, w + 1);
		}
	}

	pd(best);
}


#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <set>
#include <iomanip>
#include <fstream>
#include <cstdint>
#include <cmath>
#include <algorithm>
#include <utility>
#include <numeric>
#include <functional>
using namespace std;

constexpr int INF       = 1000000000;/* 1e+9a */
constexpr int MODULO    = 1000000007;

#define int int64_t

#define REP(i,f,n) for(int i=(f); i < (n); ++i)
#define PER(i,f,n) for(int i=(n-1); i >= f; --i)

constexpr int dx[4] = { 1, 0, -1, 0 };
constexpr int dy[4] = { 0, 1, 0, -1 };

template<typename STL> inline void print_STL(STL c, string ab = ""){
	cout << ab << '\n';
	for(auto t : c) cout << t << ' ';}

template<typename VEC> inline void import_VEC(VEC& c, int n){
	typename VEC::value_type tmp;
	for(int i = 0; i < n; ++i){	cin >> tmp; c.push_back(tmp);} }

vector<int> wei, beu;

struct hos
{
	int num;
	int w;
	int v;
	hos(int a) :num(a), w(wei[a]), v(beu[a]) {}
};

bool operator<(hos a, hos b)
{
	return a.w < b.w;
}

int n, m, w;
vector<set<hos>> fgroups;

bool is_noins(int a, int b)
{
	REP(j, 0, fgroups.size())
	{
		if(fgroups[j].count(a) || fgroups[j].count(b))
		{
			fgroups[j].insert(a), fgroups[j].insert(b);
			return false;
		}
	}
	return true;
}

int solve()
{
	vector<int> sval, swei;
	REP(i, 0, fgroups.size())
	{
		int we = 0;
		int va = 0;
		for(auto x : fgroups[i])
		{
			we += x.w;
			va += x.v;
		}
		sval.push_back(va);
		swei.push_back(we);
	}

	int dp[1010][1010]= {};
	REP(i, 0, fgroups.size())
	{
		REP(j, 0, fgroups[i].begin()->w)
			dp[i+1][j] = dp[i][j];
		for(auto h : fgroups[i])
		{
			REP(j, h.w, w+1)
			  dp[i+1][j] = max(max(dp[i+1][j], dp[i][j]),  dp[i][j-h.w] + h.v);
		}
		REP(j, swei[i], w+1)
			  dp[i+1][j] = max(dp[i+1][j], dp[i][j-swei[i]] + sval[i]);
	}

	return dp[fgroups.size()][w];

}

signed main()
{
	cin.tie(0);
    ios::sync_with_stdio(false);
	cin >> n >> m >> w;

	import_VEC(wei, n);
	import_VEC(beu, n);
	bool grouped[n] = {};

	REP(i, 0, m)
	{
		int a, b;
		cin >> a >> b;
		a--;
		b--;
		if(is_noins(a, b))
		{
			fgroups.push_back({hos(a), hos(b)});
		}
			grouped[a] = true;
			grouped[b] = true;
	}

	REP(i, 0, n)
		if(!grouped[i])
			fgroups.push_back({hos(i)});

	/* for(auto x : fgroups) */
	/* { */
	/* 	for(auto v : x) */
	/* 		cout << ' ' << v.num << ',' << v.w << ',' << v.v; */
	/* 	cout << '\n'; */
	/* } */

	cout << solve() << '\n';

}


#include <iostream>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <iomanip>
#include <fstream>
#include <cstdint>
#include <cmath>
#include <algorithm>
#include <utility>
#include <numeric>
#include <functional>
using namespace std;

#define int int64_t

#define REP(i,f,n) for(int i=(f); i < (n); ++i)
#define PER(i,f,n) for(int i=(n-1); i >= f; --i)

template<typename VEC> inline void import_VEC(VEC& c, int n){
	typename VEC::value_type tmp;
	for(int i = 0; i < n; ++i){	cin >> tmp; c.push_back(tmp);} }

vector<int> wei, beu;

int n, m, w;
vector<set<int>> fgroups;

int solve()
{
	vector<int> sval, swei;
	REP(i, 0, fgroups.size())
	{
		int we = 0;
		int va = 0;
		for(auto x : fgroups[i])
		{
			we += wei[x];
			va += beu[x];
		}
		sval.push_back(va);
		swei.push_back(we);
	}

	int dp[1010][1010]= {};
	REP(i, 0, fgroups.size())
	{
		REP(j, 0, w+1)
			dp[i+1][j] = dp[i][j];
		for(auto h : fgroups[i])
		{
			REP(j, wei[h], w+1)
			  dp[i+1][j] = max(dp[i+1][j],  dp[i][j-wei[h]] + beu[h]);
		}
		REP(j, swei[i], w+1)
			  dp[i+1][j] = max(dp[i+1][j], dp[i][j-swei[i]] + sval[i]);
	}

	return dp[fgroups.size()][w];

}

signed main()
{
	cin.tie(0);
    ios::sync_with_stdio(false);
	cin >> n >> m >> w;

	import_VEC(wei, n);
	import_VEC(beu, n);
	vector<bool> grouped(n, false);
	vector<vector<int>> gg(n,vector<int>());

	REP(i, 0, m)
	{
		int a, b;
		cin >> a >> b;
		a--;
		b--;
		gg[a].push_back(b);
		gg[b].push_back(a);
	}
	stack<int> se;

	REP(i, 0, n)
	{
		if(grouped[i])
			continue;
		fgroups.push_back({i});
		grouped[i] = true;
		for(auto x : gg[i])
		{
			if(grouped[x])
				continue;
			fgroups.back().insert(x);
			grouped[x] = true;
			se.push(x);
		}
		while(se.size())
		{
			auto tmp = se.top();
			se.pop();
			for(auto x : gg[tmp])
			{
				if(grouped[x])
					continue;
				fgroups.back().insert(x);
				grouped[x] = true;
				se.push(x);
			}
		}
	}
	REP(i, 0, n)
		if(!grouped[i])
			fgroups.push_back({i});

	/* for(auto vv : fgroups) */
	/* { */
	/* 	for(auto v : vv) */
	/* 		cout << v << ' '; */
	/* 	cout << '\n'; */
	/* } */

	REP(i, 0, n)
	{
		if(!grouped[i])
			fgroups.push_back({i});
	}

	cout << solve() << '\n';
}


#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <set>
#include <iomanip>
#include <fstream>
#include <cstdint>
#include <cmath>
#include <algorithm>
#include <utility>
#include <numeric>
#include <functional>
using namespace std;

constexpr int INF       = 1000000000;/* 1e+9a */
constexpr int MODULO    = 1000000007;

#define int int64_t

#define REP(i,f,n) for(int i=(f); i < (n); ++i)
#define PER(i,f,n) for(int i=(n-1); i >= f; --i)

constexpr int dx[4] = { 1, 0, -1, 0 };
constexpr int dy[4] = { 0, 1, 0, -1 };

template<typename STL> inline void print_STL(STL c, string ab = ""){
	cout << ab << '\n';
	for(auto t : c) cout << t << ' ';}

template<typename VEC> inline void import_VEC(VEC& c, int n){
	typename VEC::value_type tmp;
	for(int i = 0; i < n; ++i){	cin >> tmp; c.push_back(tmp);} }

vector<int> wei, beu;

struct hos
{
	int num;
	int w;
	int v;
	hos(int a) :num(a), w(wei[a]), v(beu[a]) {}
};

bool operator<(hos a, hos b)
{
	return a.w < b.w;
}

int n, m, w;
vector<set<hos>> fgroups;

bool is_noins(int a, int b)
{
	REP(j, 0, fgroups.size())
	{
		if(fgroups[j].count(a) || fgroups[j].count(b))
		{
			fgroups[j].insert(a), fgroups[j].insert(b);
			return false;
		}
	}
	return true;
}

int solve()
{
	vector<int> sval, swei;
	REP(i, 0, fgroups.size())
	{
		int we = 0;
		int va = 0;
		for(auto x : fgroups[i])
		{
			we += x.w;
			va += x.v;
		}
		sval.push_back(va);
		swei.push_back(we);
	}

	int dp[1010][1010]= {};
	REP(i, 0, fgroups.size())
	{
		REP(j, 0, fgroups[i].begin()->w)
			dp[i+1][j] = dp[i][j];
		for(auto h : fgroups[i])
		{
			REP(j, h.w, w+1)
			  dp[i+1][j] = max(max(dp[i+1][j], dp[i][j]),  dp[i][j-h.w] + h.v);
		}
		REP(j, swei[i], w+1)
			  dp[i+1][j] = max(dp[i+1][j], dp[i][j-swei[i]] + sval[i]);
	}

	return dp[fgroups.size()][w];

}

signed main()
{
	cin.tie(0);
    ios::sync_with_stdio(false);
	cin >> n >> m >> w;

	import_VEC(wei, n);
	import_VEC(beu, n);
	vector<bool> grouped(n, false);

	REP(i, 0, m)
	{
		int a, b;
		cin >> a >> b;
		a--;
		b--;
		if(is_noins(a, b))
		{
			fgroups.push_back({hos(a), hos(b)});
		}
			grouped[a] = true;
			grouped[b] = true;
	}

	REP(i, 0, n)
		if(!grouped[i])
			fgroups.push_back({hos(i)});

	cout << solve() << '\n';

}


#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <set>
#include <iomanip>
#include <fstream>
#include <cstdint>
#include <cmath>
#include <algorithm>
#include <utility>
#include <numeric>
#include <functional>
using namespace std;

constexpr int INF       = 1000000000;/* 1e+9a */
constexpr int MODULO    = 1000000007;

#define int int64_t

#define REP(i,f,n) for(int i=(f); i < (n); ++i)
#define PER(i,f,n) for(int i=(n-1); i >= f; --i)

constexpr int dx[4] = { 1, 0, -1, 0 };
constexpr int dy[4] = { 0, 1, 0, -1 };

template<typename STL> inline void print_STL(STL c, string ab = ""){
	cout << ab << '\n';
	for(auto t : c) cout << t << ' ';}

template<typename VEC> inline void import_VEC(VEC& c, int n){
	typename VEC::value_type tmp;
	for(int i = 0; i < n; ++i){	cin >> tmp; c.push_back(tmp);} }

vector<int> wei, beu;

struct hos
{
	int num;
	int w;
	int v;
	hos(int a) :num(a), w(wei[a]), v(beu[a]) {}
};

bool operator<(hos a, hos b)
{
	return a.w < b.w;
}

int n, m, w;
vector<set<hos>> fgroups;

bool is_noins(int a, int b)
{
	REP(j, 0, fgroups.size())
	{
		if(fgroups[j].count(a) || fgroups[j].count(b))
		{
			fgroups[j].insert(a), fgroups[j].insert(b);
			return false;
		}
	}
	return true;
}

int solve()
{
	vector<int> sval, swei;
	REP(i, 0, fgroups.size())
	{
		int we = 0;
		int va = 0;
		for(auto x : fgroups[i])
		{
			we += x.w;
			va += x.v;
		}
		sval.push_back(va);
		swei.push_back(we);
	}

	int dp[1010][1010]= {};
	REP(i, 0, fgroups.size())
	{
		int now = i+1;
		REP(j, 0, w+1)
			dp[now][j] = dp[now-1][j];
		for(auto h : fgroups[i])
			REP(j, h.w, w+1)
			{
				/* cout << i << ':' << j << "::" */
					  (dp[now][j] = max(dp[now][j], dp[now-1][j-h.w] + h.v));
			}
		REP(j, swei[i], w+1)
			/* cout << i << ':' << j << "::" */
				  (dp[now][j] = max(dp[now][j], dp[now-1][j-swei[i]] + sval[i]));
	}

	return dp[fgroups.size()][w];

}

signed main()
{
	cin.tie(0);
    ios::sync_with_stdio(false);
	cin >> n >> m >> w;

	import_VEC(wei, n);
	import_VEC(beu, n);
	bool grouped[n] = {};

	REP(i, 0, m)
	{
		int a, b;
		cin >> a >> b;
		a--;
		b--;
		if(is_noins(a, b))
		{
			fgroups.push_back({hos(a), hos(b)});
		}
			grouped[a] = true;
			grouped[b] = true;
	}

	REP(i, 0, n)
		if(!grouped[i])
			fgroups.push_back({hos(i)});

	/* for(auto x : fgroups) */
	/* { */
	/* 	for(auto v : x) */
	/* 		cout << ' ' << v.num << ',' << v.w << ',' << v.v; */
	/* 	cout << '\n'; */
	/* } */

	cout << solve() << '\n';

}


#include <iostream>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <iomanip>
#include <fstream>
#include <cstdint>
#include <cmath>
#include <algorithm>
#include <utility>
#include <numeric>
#include <functional>
using namespace std;

#define int int64_t

#define REP(i,f,n) for(int i=(f); i < (n); ++i)
#define PER(i,f,n) for(int i=(n-1); i >= f; --i)

template<typename VEC> inline void import_VEC(VEC& c, int n){
	typename VEC::value_type tmp;
	for(int i = 0; i < n; ++i){	cin >> tmp; c.push_back(tmp);} }

vector<int> wei, beu;

int n, m, w;
vector<set<int>> fgroups;

int solve()
{
	vector<int> sval, swei;
	REP(i, 0, fgroups.size())
	{
		int we = 0;
		int va = 0;
		for(auto x : fgroups[i])
		{
			we += wei[x];
			va += beu[x];
		}
		sval.push_back(va);
		swei.push_back(we);
	}

	int dp[1010][1010]= {};
	REP(i, 0, fgroups.size())
	{
		REP(j, 0, w+1)
			dp[i+1][j] = dp[i][j];
		for(auto h : fgroups[i])
		{
			REP(j, wei[h], w+1)
			  dp[i+1][j] = max(dp[i+1][j],  dp[i][j-wei[h]] + beu[h]);
		}
		REP(j, swei[i], w+1)
			  dp[i+1][j] = max(dp[i+1][j], dp[i][j-swei[i]] + sval[i]);
	}

	return dp[fgroups.size()][w];

}

signed main()
{
	cin.tie(0);
    ios::sync_with_stdio(false);
	cin >> n >> m >> w;

	import_VEC(wei, n);
	import_VEC(beu, n);
	vector<bool> grouped(n, false);
	vector<vector<int>> gg(n,vector<int>());

	REP(i, 0, m)
	{
		int a, b;
		cin >> a >> b;
		a--;
		b--;
		gg[a].push_back(b);
		gg[b].push_back(a);
	}
	stack<int> se;

	REP(i, 0, n)
	{
		if(grouped[i])
			continue;
		fgroups.push_back({i});
		grouped[i] = true;
		for(auto x : gg[i])
		{
			if(grouped[x])
				continue;
			fgroups.back().insert(x);
			grouped[x] = true;
			se.push(x);
		}
		while(se.size())
		{
			auto tmp = se.top();
			se.pop();
			for(auto x : gg[tmp])
			{
				if(grouped[x])
					continue;
				fgroups.back().insert(x);
				grouped[x] = true;
				se.push(x);
			}
		}
	}
	REP(i, 0, n)
		if(!grouped[i])
			fgroups.push_back({i});

	for(auto vv : fgroups)
	{
		for(auto v : vv)
			cout << v << ' ';
		cout << '\n';
	}

	REP(i, 0, n)
	{
		if(!grouped[i])
			fgroups.push_back({i});
	}

	cout << solve() << '\n';
}


#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <set>
#include <iomanip>
#include <fstream>
#include <cstdint>
#include <cmath>
#include <algorithm>
#include <utility>
#include <numeric>
#include <functional>
using namespace std;

#define int int64_t

#define REP(i,f,n) for(int i=(f); i < (n); ++i)
#define PER(i,f,n) for(int i=(n-1); i >= f; --i)

template<typename VEC> inline void import_VEC(VEC& c, int n){
	typename VEC::value_type tmp;
	for(int i = 0; i < n; ++i){	cin >> tmp; c.push_back(tmp);} }

vector<int> wei, beu;

int n, m, w;
vector<set<int>> fgroups;

bool is_noins(int a, int b)
{
	/* cout << "is::" << a << ',' << b << '\n'; */
	set<int> is_in;
	REP(j, 0, fgroups.size())
	{
		if(fgroups[j].count(a) || fgroups[j].count(b))
			is_in.insert(j);
	}

	if(is_in.size())
	{
		int to = *is_in.begin();
		fgroups[to].insert(a);
		fgroups[to].insert(b);
		for(auto s : is_in)
		{
			for(auto tm : fgroups[s])
				fgroups[to].insert(tm);
			if(s != to)
				fgroups[s] = {};
		}
		return false;
	}
	else
		return true;

}

int solve()
{
	vector<int> sval, swei;
	REP(i, 0, fgroups.size())
	{
		int we = 0;
		int va = 0;
		for(auto x : fgroups[i])
		{
			we += wei[x];
			va += beu[x];
		}
		sval.push_back(va);
		swei.push_back(we);
	}

	int dp[1010][1010]= {};
	REP(i, 0, fgroups.size())
	{
		REP(j, 0, w+1)
			dp[i+1][j] = dp[i][j];
		for(auto h : fgroups[i])
		{
			REP(j, wei[h], w+1)
			  dp[i+1][j] = max(dp[i+1][j],  dp[i][j-wei[h]] + beu[h]);
		}
		REP(j, swei[i], w+1)
			  dp[i+1][j] = max(dp[i+1][j], dp[i][j-swei[i]] + sval[i]);
	}

	return dp[fgroups.size()][w];

}

signed main()
{
	cin.tie(0);
    ios::sync_with_stdio(false);
	cin >> n >> m >> w;

	import_VEC(wei, n);
	import_VEC(beu, n);
	vector<bool> grouped(n, false);

	REP(i, 0, m)
	{
		int a, b;
		cin >> a >> b;
		a--;
		b--;
		if(is_noins(a, b))
		{
			fgroups.push_back({a,b});
		}
		grouped[a] = true;
		grouped[b] = true;
	}

	/* for(auto vv : fgroups) */
	/* { */
	/* 	for(auto v : vv) */
	/* 		cout << v << ' '; */
	/* 	cout << '\n'; */
	/* } */

	REP(i, 0, n)
	{
		if(!grouped[i])
			fgroups.push_back({i});
	}

	cout << solve() << '\n';
}


#include<bits/stdc++.h>
using namespace std;
const int N(1024), W(1024);
void dp(int x);
int find(int x);
void uni(int x, int y);

bool seen[N];
vector<vector<int>> mem;
int n, m, w, ww[N], bb[N], pp[N];
int d[W], ans;
vector<int> dy[N];
int main()
{
 scanf("%d%d%d", &n, &m, &w), mem.resize(n+1);
 for (int i = 1; i <= n; i++) scanf("%d", ww + i);
 for (int i = 1; i <= n; i++) scanf("%d", bb + i);
 for (int i = 1; i <= n; i++) pp[i] = i, mem[i].push_back(i);
 for (int x, y; m--;) scanf("%d%d", &x, &y), uni(x, y);

 for (int x, i = 1; i <= n; i++) if (!seen[x = find(i)]) {
  printf("%d,", x);
  dp(x), seen[x] = true;
  for (int k = w; k >= 0; k--)
   for (int j = w-k; j >= 0; j--)
    d[k+j] = max(d[k+j], d[k] + dy[x][j]),
    ans = max(d[k+j], ans);
 }

 printf("%d\n", ans);
 return 0;
}

int find(int x) { return pp[x] = x != pp[x] ? find(pp[x]) : x; }
void uni(int x, int y) {
 x = find(x), y = find(y);
 if (mem[x].size() < mem[y].size()) swap(x, y);
 pp[y] = pp[x];
 mem[x].insert(mem[x].end(), mem[y].begin(), mem[y].end());
}

void dp(int x)
{
 auto &d = dy[x];
 d.clear(), d.resize(w+1, 0);

 int s_w = 0, s_b = 0;
 for (auto& i: mem[x]) {
  s_w += ww[i];
  s_b += bb[i];
  if (ww[i] <= w) d[ww[i]] = max(d[ww[i]], bb[i]);
 }

 if (s_w <= w) d[s_w] = max(d[s_w], s_b);
}


#include<bits/stdc++.h>
using namespace std;
const int N(1024), W(1024);
int find(int x);
void uni(int x, int y);

bool seen[N];
vector<vector<int>> mem;
int n, m, w, ww[N], bb[N], pp[N];
int d[W], ans;
int main()
{
 scanf("%d%d%d", &n, &m, &w), mem.resize(N);
 for (int i = 1; i <= n; i++) scanf("%d", ww + i);
 for (int i = 1; i <= n; i++) scanf("%d", bb + i);
 for (int i = 1; i <= n; i++) pp[i] = i, mem[i].push_back(i);
 for (int x, y; m--;) scanf("%d%d", &x, &y), uni(x, y);

 for (int x, i = 1; i <= n; i++) if (!seen[find(i)]) {
  x = find(i), seen[x] = true;
  for (int k = w; k >= 0; k--) {
   int sw = 0, sb = 0;
   for (auto& p: mem[x]) {
    int j = ww[p];
    if (k+j <= w) {
     d[k+j] = max(d[k+j], d[k] + bb[p]);
     ans = max(d[k+j], ans);
    }
    sw += j; sb += bb[p];
   }
   if (k + sw <= w) d[k+sw] = max(d[k+sw], d[k] + sb), ans = max(ans, d[k+sw]);
  }
 }

 printf("%d\n", ans);
 return 0;
}

int find(int x) { return pp[x] = x != pp[x] ? find(pp[x]) : x; }
void uni(int x, int y) {
 x = find(x), y = find(y);
 if (mem[x].size() < mem[y].size()) swap(x, y);
 pp[y] = pp[x];
 mem[x].insert(mem[x].end(), mem[y].begin(), mem[y].end());
}


#include<bits/stdc++.h>
using namespace std;
const int N(1024), W(1024);
int find(int x);
void uni(int x, int y);

bool seen[N];
vector<vector<int>> mem;
int n, m, w, ww[N], bb[N], pp[N];
int d[W], ans;
int main()
{
 scanf("%d%d%d", &n, &m, &w), mem.resize(N);
 for (int i = 1; i <= n; i++) scanf("%d", ww + i);
 for (int i = 1; i <= n; i++) scanf("%d", bb + i);
 for (int i = 1; i <= n; i++) pp[i] = i, mem[i].push_back(i);
 for (int x, y; m--;) scanf("%d%d", &x, &y), uni(x, y);

 for (int x, i = 1; i <= n; i++) if (!seen[find(i)]) {
  x = find(i), seen[x] = true;
  for (int k = w; k >= 0; k--) {
   int sw = 0, sb = 0;
   for (auto& p: mem[x]) {
    int j = ww[p];
    if (k+j <= w) {
     d[k+j] = max(d[k+j], d[k] + bb[p]);
     ans = max(d[k+j], ans);
    }
    sw += j; sb += bb[p];
   }
   if (k + sw <= w)
    d[k+sw] = max(d[k+sw], d[k] + sb), ans = max(ans, d[k+sw]);
  }
 }

 printf("%d\n", ans);
 return 0;
}

int find(int x) { return pp[x] = x != pp[x] ? find(pp[x]) : x; }
void uni(int x, int y) {
 x = find(x), y = find(y);
 if (mem[x].size() < mem[y].size()) swap(x, y);
 mem[x].insert(mem[x].end(), mem[y].begin(), mem[y].end());
 mem[y].clear();
 pp[y] = pp[x];
 find(y);
}


#include<bits/stdc++.h>
using namespace std;
const int N(1024), W(1024);
void dp(int x);
int find(int x);
void uni(int x, int y);

bool seen[N];
vector<vector<int>> mem;
int n, m, w, ww[N], bb[N], pp[N];
int d[W], ans;
vector<int> dy[N];
int main()
{
 scanf("%d%d%d", &n, &m, &w), mem.resize(n+1);
 for (int i = 1; i <= n; i++) scanf("%d", ww + i);
 for (int i = 1; i <= n; i++) scanf("%d", bb + i);
 for (int i = 1; i <= n; i++) pp[i] = i, mem[i].push_back(i);
 for (int x, y; m--;) scanf("%d%d", &x, &y), uni(x, y);

 for (int x, i = 1; i <= n; i++) if (!seen[x = find(i)]) {
  dp(x), seen[x] = true;
  for (int k = w; k >= 0; k--)
   for (int j = w-k; j >= 0; j--)
    d[k+j] = max(d[k+j], d[k] + dy[x][j]),
    ans = max(d[k+j], ans);
 }

 printf("%d\n", ans);
 return 0;
}

int find(int x) { return pp[x] = x != pp[x] ? find(pp[x]):x; }
void uni(int x, int y) {
 if (mem[x = find(x)].size() < mem[y = find(y)].size()) swap(x, y);
 pp[y] = pp[x];
 mem[x].insert(mem[x].end(), mem[y].begin(), mem[y].end());
}

void dp(int x)
{
 auto &d = dy[x];
 d.clear(), d.resize(W, 0);

 int s_w = 0, s_b = 0;
 for (auto& i: mem[x]) {
  s_w += ww[i];
  s_b += bb[i];
  if (ww[i] <= w) d[ww[i]] = max(d[ww[i]], bb[i]);
 }

 if (s_w <= w) d[s_w] = max(d[s_w], s_b);
}


#include<bits/stdc++.h>
using namespace std;
const int N(1024), W(1024);
int find(int x);
void uni(int x, int y);

bool seen[N];
vector<vector<int>> mem;
int n, m, w, ww[N], bb[N], pp[N];
int d[W], ans;
int main()
{
 scanf("%d%d%d", &n, &m, &w), mem.resize(N);
 for (int i = 1; i <= n; i++) scanf("%d", ww + i);
 for (int i = 1; i <= n; i++) scanf("%d", bb + i);
 for (int i = 1; i <= n; i++) pp[i] = i, mem[i].push_back(i);
 for (int x, y; m--;) scanf("%d%d", &x, &y), uni(x, y), printf("%d--%d\n", x, y);

 for (int x, i = 1; i <= n; i++) if (!seen[find(i)]) {
  x = find(i), seen[x] = true;
  for (int k = w; k >= 0; k--) {
   int sw = 0, sb = 0;
   for (auto& p: mem[x]) {
    int j = ww[p];
    if (k+j <= w) {
     d[k+j] = max(d[k+j], d[k] + bb[p]);
     ans = max(d[k+j], ans);
    }
    sw += j; sb += bb[p];
   }
   if (k + sw <= w)
    d[k+sw] = max(d[k+sw], d[k] + sb), ans = max(ans, d[k+sw]);
  }
 }

 printf("%d\n", ans);
 return 0;
}

int find(int x) { return pp[x] = x != pp[x] ? find(pp[x]) : x; }
void uni(int x, int y) {
 x = find(x), y = find(y);
 if (x != y) {
  if (mem[x].size() < mem[y].size()) swap(x, y);
  for (auto& z: mem[y]) mem[x].emplace_back(z);
  printf("%d ==> %d\n", x, y);
  pp[y] = pp[x];
  mem[y].clear();
 }
}


#include<bits/stdc++.h>
using namespace std;
const int N(1024), W(1024);
void dp(int x);
int find(int x);
void uni(int x, int y);

bool seen[N];
vector<vector<int>> mem;
int n, m, w, ww[N], bb[N], pp[N];
int d[W], ans;
vector<int> dy[N];
int main()
{
 scanf("%d%d%d", &n, &m, &w), mem.resize(n+1);
 for (int i = 1; i <= n; i++) scanf("%d", ww + i);
 for (int i = 1; i <= n; i++) scanf("%d", bb + i);
 for (int i = 1; i <= n; i++) pp[i] = i, mem[i].push_back(i);
 for (int x, y; m--;) scanf("%d%d", &x, &y), uni(x, y);

 for (int x, i = 1; i <= n; i++) if (!seen[x = find(i)]) {
  dp(x), seen[x] = true;
  for (int k = w; k >= 0; k--)
   for (int j = w-k; j >= 0; j--)
    d[k+j] = max(d[k+j], d[k] + dy[x][j]),
    ans = max(d[k+j], ans);
 }

 printf("%d\n", ans);
 return 0;
}

int find(int x) { return pp[x] = x != pp[x] ? find(pp[x]):x; }
void uni(int x, int y) {
 if (mem[x = find(x)].size() < mem[y = find(y)].size()) swap(x, y);
 pp[y] = pp[x];
 mem[x].insert(mem[x].end(), mem[y].begin(), mem[y].end());
}

void dp(int x)
{
 auto &d = dy[x];
 d.clear(), d.resize(w+1, 0);

 int s_w = 0, s_b = 0;
 for (auto& i: mem[x]) {
  s_w += ww[i];
  s_b += bb[i];
  if (ww[i] <= w) d[ww[i]] = max(d[ww[i]], bb[i]);
 }

 if (s_w <= w) d[s_w] = max(d[s_w], s_b);
}


#include<bits/stdc++.h>
using namespace std;
const int N(1024), W(1024);
void dp(int x);
int find(int x);
void uni(int x, int y);

bool seen[N];
vector<vector<int>> mem;
int n, m, w, ww[N], bb[N], pp[N];
int d[W], ans;
vector<int> dy[N];
int main()
{
 scanf("%d%d%d", &n, &m, &w), mem.resize(n+1);
 for (int i = 1; i <= n; i++) scanf("%d", ww + i);
 for (int i = 1; i <= n; i++) scanf("%d", bb + i);
 for (int i = 1; i <= n; i++) pp[i] = i, mem[i].push_back(i);
 for (int x, y; m--;) scanf("%d%d", &x, &y), uni(x, y);

 for (int x, i = 1; i <= n; i++) if (!seen[x = find(i)]) {
  dp(x), seen[x] = true;
  for (int k = w; k >= 0; k--)
   for (int j = w-k; j >= 0; j--)
    d[k+j] = max(d[k+j], d[k] + dy[x][j]),
    ans = max(d[k+j], ans);
 }

 printf("%d\n", ans);
 return 0;
}

int find(int x) { return pp[x] = x != pp[x] ? find(pp[x]):x; }
void uni(int x, int y) {
 if (mem[x = find(x)].size() < mem[y = find(y)].size()) swap(x, y);
 pp[y] = pp[x];
 mem[x].insert(mem[x].end(), mem[y].begin(), mem[y].end());mem[y].clear();
}

void dp(int x)
{
 auto &d = dy[x];
 d.clear(), d.resize(W, 0);

 int s_w = 0, s_b = 0;
 for (auto& i: mem[x]) {
  s_w += ww[i];
  s_b += bb[i];
  if (ww[i] <= w) d[ww[i]] = max(d[ww[i]], bb[i]);
 }

 if (s_w <= w) d[s_w] = max(d[s_w], s_b);
}


#include<bits/stdc++.h>
using namespace std;
const int N(1024), W(1024);
void dp(int x);
int find(int x);
void uni(int x, int y);

bool seen[N];
vector<vector<int>> mem;
int n, m, w, ww[N], bb[N], pp[N];
int d[W], ans;
vector<int> dy[N];
int main()
{
 scanf("%d%d%d", &n, &m, &w), mem.resize(n+1);
 for (int i = 1; i <= n; i++) scanf("%d", ww + i);
 for (int i = 1; i <= n; i++) scanf("%d", bb + i);
 for (int i = 1; i <= n; i++) pp[i] = i, mem[i].push_back(i);
 for (int x, y; m--;) scanf("%d%d", &x, &y), uni(x, y);

 for (int x, i = 1; i <= n; i++) if (!seen[x = find(i)]) {
  dp(x), seen[x] = true;
  for (int k = w; k >= 0; k--)
   for (int j = w-k; j >= 0; j--)
    d[k+j] = max(d[k+j], d[k] + dy[x][j]),
    ans = max(d[k+j], ans);
 }

 printf("%d\n", ans);
 return 0;
}

int find(int x) { return pp[x] = x != pp[x] ? find(pp[x]) : x; }
void uni(int x, int y) {
 x = find(x), y = find(y);
 if (mem[x].size() < mem[y].size()) swap(x, y);
 pp[y] = pp[x];
 mem[x].insert(mem[x].end(), mem[y].begin(), mem[y].end());
}

void dp(int x)
{
 auto &d = dy[x];
 d.clear(), d.resize(w+1, 0);

 int s_w = 0, s_b = 0;
 for (auto& i: mem[x]) {
  s_w += ww[i];
  s_b += bb[i];
  if (ww[i] <= w) d[ww[i]] = max(d[ww[i]], bb[i]);
 }

 if (s_w <= w) d[s_w] = max(d[s_w], s_b);
}


 #include<bits/stdc++.h>
using namespace std;
const int N(1024), W(1024);
int find(int x);
void uni(int x, int y);

bool seen[N];
vector<vector<int>> mem;
int n, m, w, ww[N], bb[N], pp[N];
int d[W], ans;
int main()
{
 scanf("%d%d%d", &n, &m, &w), mem.resize(N);
 for (int i = 1; i <= n; i++) scanf("%d", ww + i);
 for (int i = 1; i <= n; i++) scanf("%d", bb + i);
 for (int i = 1; i <= n; i++) pp[i] = i, mem[i].push_back(i);
 for (int x, y; m--;) scanf("%d%d", &x, &y), uni(x, y);

 for (int x, i = 1; i <= n; i++) if (!seen[find(i)]) {
  x = find(i), seen[x] = true;
  for (int k = w; k >= 0; k--) {
   int sw = 0, sb = 0;
   for (auto& p: mem[x]) {
    int j = ww[p];
    if (k+j <= w) {
     d[k+j] = max(d[k+j], d[k] + bb[p]);
     ans = max(d[k+j], ans);
    }
    sw += j; sb += bb[p];
   }
   if (k + sw <= w)
    d[k+sw] = max(d[k+sw], d[k] + sb), ans = max(ans, d[k+sw]);
  }
 }

 printf("%d\n", ans);
 return 0;
}

int find(int x) { return pp[x] = x != pp[x] ? find(pp[x]) : x; }
void uni(int x, int y) {
 x = find(x), y = find(y);
 if (x != y) {
  if (mem[x].size() < mem[y].size()) swap(x, y);
  for (auto& z: mem[y]) mem[x].emplace_back(z);
  pp[y] = pp[x];
  mem[y].clear();
 }
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e3+100;

ll n , m , s;

ll w[maxn] , b[maxn];

ll dp[2][maxn];

ll cnt;
vector <ll> g[maxn] , CONN[maxn];

ll v[maxn];

int main(){
	cin >> n >> m >> s;
	for (ll i = 1;i <= n;i++) cin >> w[i];
	for (ll i = 1;i <= n;i++) cin >> b[i];

	for (ll i = 0;i < m;i++){
		ll x,y; cin >> x >> y;
		CONN[x].push_back(y);
		CONN[y].push_back(x);
	}
	cnt = 0;
	for (ll i = 1;i <= n;i++){
		if (v[i]) continue;
		queue <ll> Q; Q.push(i);
		cnt ++;
		while (not Q.empty()){
			ll act = Q.front(); Q.pop();
			v[act] = 1;
			g[cnt].push_back(act);
			for (ll j = 0;j < CONN[act].size();j++){
				if (v[CONN[act][j]]) continue;
				//v[CONN[act][j]] = 1;
				Q.push(CONN[act][j]);
			}
		}
	}

	for (ll i = 0;i <= s;i++) dp[0][i] = 0; // no items

	for (ll i = 1;i <= cnt;i++){ // for each group
		for (ll j = 0;j <= s;j++){ // for each weight
			dp[i%2][j] = dp[(i-1)%2][j]; // not using any item
			ll tw = 0, tb = 0;
			for (ll k =0;k < g[i].size();k++){
				if (j - w[ g[i][k] ] >= 0){
					dp[i%2][j] = max( dp[i%2][j] , dp[(i-1)%2][j - w[ g[i][k] ]] + b[ g[i][k]]);
				}
				tw += w[ g[i][k] ];
				tb += b[ g[i][k ]];
			}
			if (j - tw >= 0) dp[i%2][j] = max(dp[i%2][j] , dp[(i-1)%2][j - tw] + tb);
		}
	}

	cout << dp[cnt%2][s] << '\n';
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e3+100;

int n , m , s;

int w[maxn] , b[maxn];

int dp[maxn][maxn];

int cnt;
vector <int> g[maxn] , CONN[maxn];

int v[maxn];

int main(){
	scanf("%d%d%d",&n,&m,&s);
	for (int i = 1;i <= n;i++) scanf("%d",&w[i]);
	for (int i = 1;i <= n;i++) scanf("%d",&b[i]);

	for (int i = 0;i < m;i++){
		int x,y; scanf("%d%d",&x,&y);
		CONN[x].push_back(y);
		CONN[y].push_back(x);
	}
	cnt = 0;
	for (int i = 1;i <= n;i++){
		if (v[i]) continue;
		queue <int> Q; Q.push(i);
		cnt ++;
		while (not Q.empty()){
			int act = Q.front(); Q.pop();
			v[act] = 1;
			g[cnt].push_back(act);
			for (int j = 0;j < CONN[act].size();j++){
				if (v[CONN[act][j]]) continue;
				v[CONN[act][j]] = 1;
				Q.push(CONN[act][j]);
			}
		}
	}

	for (int i = 0;i <= s;i++) dp[0][i] = 0; // no items

	for (int i = 1;i <= cnt;i++){ // for each group
		for (int j = 0;j <= s;j++){ // for each weight
			dp[i][j] = dp[i-1][j]; // not using any item
			int tw = 0, tb = 0;
			for (int k = 0;k < g[i].size();k++){
				if (j - w[ g[i][k] ] >= 0){
					dp[i][j] = max( dp[i][j] , dp[i-1][j - w[ g[i][k] ]] + b[ g[i][k]]);
				}
				tw += w[ g[i][k] ];
				tb += b[ g[i][k] ];
			}
			if (j - tw >= 0){
				dp[i][j] = max(dp[i][j] , dp[i-1][j - tw] + tb);
			}
		}
	}

	printf("%d\n",dp[cnt][s]);
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e3+100;

int n , m , s;

ll w[maxn] , b[maxn];

ll dp[maxn][maxn];

int cnt;
vector <int> g[maxn] , CONN[maxn];

int v[maxn];

int main(){
	cin >> n >> m >> s;
	for (int i = 1;i <= n;i++) cin >> w[i];
	for (int i = 1;i <= n;i++) cin >> b[i];

	for (int i = 0;i < m;i++){
		int x,y; cin >> x >> y;
		CONN[x].push_back(y);
		CONN[y].push_back(x);
	}
	cnt = 0;
	for (int i = 1;i <= n;i++){
		if (v[i]) continue;
		queue <int> Q; Q.push(i);
		cnt ++;
		while (not Q.empty()){
			int act = Q.front(); Q.pop();
			v[act] = 1;
			g[cnt].push_back(act);
			for (int j = 0;j < CONN[act].size();j++){
				if (v[CONN[act][j]]) continue;
				//v[CONN[act][j]] = 1;
				Q.push(CONN[act][j]);
			}
		}
	}

	for (int i = 0;i <= s;i++) dp[0][i] = 0; // no items

	for (int i = 1;i <= cnt;i++){ // for each group
		for (int j = 0;j <= s;j++){ // for each weight
			dp[i][j] = dp[i-1][j]; // not using any item
			ll tw = 0, tb = 0;
			for (int k =0;k < g[i].size();k++){
				if (j - w[ g[i][k] ] >= 0){
					dp[i][j] = max( dp[i][j] , dp[i-1][j - w[ g[i][k] ]] + b[ g[i][k]]);
				}
				tw += w[ g[i][k] ];
				tb += b[ g[i][k ]];
			}
			if (j - tw >= 0) dp[i][j] = max(dp[i][j] , dp[i-1][j - tw] + tb);
		}
	}

	cout << dp[cnt][s] << '\n';
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e3+100;

int n , m , s;

long w[maxn] , b[maxn];

long dp[maxn][maxn];

int cnt;
vector <int> g[maxn] , CONN[maxn];

int v[maxn];

int main(){
	cin >> n >> m >> s;
	for (int i = 1;i <= n;i++) cin >> w[i];
	for (int i = 1;i <= n;i++) cin >> b[i];

	for (int i = 0;i < m;i++){
		int x,y; cin >> x >> y;
		CONN[x].push_back(y);
		CONN[y].push_back(x);
	}
	cnt = 0;
	for (int i = 1;i <= n;i++){
		if (v[i]) continue;
		queue <int> Q; Q.push(i);
		cnt ++;
		while (not Q.empty()){
			int act = Q.front(); Q.pop();
			v[act] = 1;
			g[cnt].push_back(act);
			for (int j = 0;j < CONN[act].size();j++){
				if (v[CONN[act][j]]) continue;
				//v[CONN[act][j]] = 1;
				Q.push(CONN[act][j]);
			}
		}
	}

	for (int i = 0;i <= s;i++) dp[0][i] = 0; // no items

	for (int i = 1;i <= cnt;i++){ // for each group
		for (int j = 0;j <= s;j++){ // for each weight
			dp[i][j] = dp[i-1][j]; // not using any item
			long tw = 0, tb = 0;
			for (int k =0;k < g[i].size();k++){
				if (j - w[ g[i][k] ] >= 0){
					dp[i][j] = max( dp[i][j] , dp[i-1][j - w[ g[i][k] ]] + b[ g[i][k]]);
				}
				tw += w[ g[i][k] ];
				tb += b[ g[i][k] ];
			}
			if (j - tw >= 0) dp[i][j] = max(dp[i][j] , dp[i-1][j - tw] + tb);
		}
	}

	cout << dp[cnt][s] << '\n';
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e3+100;

int n , m , s;

int w[maxn] , b[maxn];

int dp[maxn][maxn];

int cnt;
vector <int> g[maxn] , CONN[maxn];

int v[maxn];

int main(){
	scanf("%d%d%d",&n,&m,&s);
	for (int i = 1;i <= n;i++) scanf("%d",&w[i]);
	for (int i = 1;i <= n;i++) scanf("%d",&b[i]);

	for (int i = 0;i < m;i++){
		int x,y; scanf("%d%d",&x,&y);
		CONN[x].push_back(y);
		CONN[y].push_back(x);
	}
	cnt = 0;
	for (int i = 1;i <= n;i++){
		if (v[i]) continue;
		queue <int> Q; Q.push(i);
		cnt ++;
		while (not Q.empty()){
			int act = Q.front(); Q.pop();
			v[act] = 1;
			g[cnt].push_back(act);
			for (int j = 0;j < CONN[act].size();j++){
				if (v[CONN[act][j]]) continue;
				//v[CONN[act][j]] = 1;
				Q.push(CONN[act][j]);
			}
		}
	}

	for (int i = 0;i <= s;i++) dp[0][i] = 0; // no items

	for (int i = 1;i <= cnt;i++){ // for each group
		for (int j = 0;j <= s;j++){ // for each weight
			dp[i][j] = dp[i-1][j]; // not using any item
			int tw = 0, tb = 0;
			for (int k =0;k < g[i].size();k++){
				if (j - w[ g[i][k] ] >= 0){
					dp[i][j] = max( dp[i][j] , dp[i-1][j - w[ g[i][k] ]] + b[ g[i][k]]);
				}
				tw += w[ g[i][k] ];
				tb += b[ g[i][k] ];
			}
			if (j - tw >= 0) dp[i][j] = max(dp[i][j] , dp[i-1][j - tw] + tb);
		}
	}

	printf("%d\n",dp[cnt][s]);
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e3+100;

int n , m , s;

ll w[maxn] , b[maxn];

ll dp[maxn][maxn];

int cnt;
vector <int> g[maxn] , CONN[maxn];

int v[maxn];

int main(){
	scanf("%d%d%d",&n,&m,&s);
	for (int i = 1;i <= n;i++) scanf(lld,&w[i]);
	for (int i = 1;i <= n;i++) scanf(lld,&b[i]);

	for (int i = 0;i < m;i++){
		int x,y; scanf("%d%d",&x,&y);
		CONN[x].push_back(y);
		CONN[y].push_back(x);
	}
	cnt = 0;
	for (int i = 1;i <= n;i++){
		if (v[i]) continue;
		queue <int> Q; Q.push(i);
		cnt ++;
		while (not Q.empty()){
			int act = Q.front(); Q.pop();
			v[act] = 1;
			g[cnt].push_back(act);
			for (int j = 0;j < CONN[act].size();j++){
				if (v[CONN[act][j]]) continue;
				//v[CONN[act][j]] = 1;
				Q.push(CONN[act][j]);
			}
		}
	}

	for (int i = 0;i <= s;i++) dp[0][i] = 0; // no items

	for (int i = 1;i <= cnt;i++){ // for each group
		for (int j = 0;j <= s;j++){ // for each weight
			dp[i][j] = dp[i-1][j]; // not using any item
			ll tw = 0, tb = 0;
			for (int k =0;k < g[i].size();k++){
				if (j - w[ g[i][k] ] >= 0){
					dp[i][j] = max( dp[i][j] , dp[i-1][j - w[ g[i][k] ]] + b[ g[i][k]]);
				}
				tw += w[ g[i][k] ];
				tb += b[ g[i][k] ];
			}
			if (j - tw >= 0) dp[i][j] = max(dp[i][j] , dp[i-1][j - tw] + tb);
		}
	}

	printf(lld,dp[cnt][s]);
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e3+100;

int n , m , s;

int w[maxn] , b[maxn];

int dp[maxn][maxn];

int cnt;
vector <int> g[maxn] , CONN[maxn];

int v[maxn];

int main(){
	scanf("%d%d%d",&n,&m,&s);
	for (int i = 1;i <= n;i++) scanf("%d",&w[i]);
	for (int i = 1;i <= n;i++) scanf("%d",&b[i]);

	for (int i = 0;i < m;i++){
		int x,y; scanf("%d%d",&x,&y);
		CONN[x].push_back(y);
		CONN[y].push_back(x);
	}
	cnt = 0;
	for (int i = 1;i <= n;i++){
		if (v[i]) continue;
		queue <int> Q; Q.push(i);
		cnt ++;
		while (not Q.empty()){
			int act = Q.front(); Q.pop();
			v[act] = 1;
			g[cnt].push_back(act);
			for (int j = 0;j < CONN[act].size();j++){
				if (v[CONN[act][j]]) continue;
				//v[CONN[act][j]] = 1;
				Q.push(CONN[act][j]);
			}
		}
	}

	for (int i = 0;i <= s;i++) dp[0][i] = 0; // no items

	for (int i = 1;i <= cnt;i++){ // for each group
		for (int j = 0;j <= s;j++){ // for each weight
			dp[i][j] = dp[i-1][j]; // not using any item
			ll tw = 0, tb = 0;
			for (int k =0;k < g[i].size();k++){
				if (j - w[ g[i][k] ] >= 0){
					dp[i][j] = max( dp[i][j] , dp[i-1][j - w[ g[i][k] ]] + b[ g[i][k]]);
				}
				tw += w[ g[i][k] ];
				tb += b[ g[i][k] ];
			}
			if (j - tw >= 0) dp[i][j] = max(dp[i][j] , dp[i-1][j - tw] + tb);
		}
	}

	printf("%d\n",dp[cnt][s]);
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e4+100;

int n , m , s;

int w[maxn] , b[maxn];

int u[maxn];

int dp[2][maxn];

int cnt;
vector <int> g[maxn];

int main(){
	cin >> n >> m >> s;
	for (int i = 1;i <= n;i++) cin >> w[i];
	for (int i = 1;i <= n;i++) cin >> b[i];
	for (int i = 0;i < m;i++){
		int x,y; cin >> x >> y;
		if (y+1 == x) u[x] = 1;
		if (x+1 == y) u[y] = 1;
	}
	cnt = 1;
	for (int i = 1;i <= n;i++){
		if (i != 1 and not u[i]) cnt ++;
		g[cnt].push_back(i);
	}

	for (int i = 0;i <= s;i++) dp[0][i] = 0; // no items
	for (int i = 1;i <= cnt;i++){ // for each group
		for (int j = 0;j <= s;j++){ // for each weight
			dp[i%2][j] = dp[(i-1)%2][j]; // not using any item
			int sb = 0 , sw = 0;
			for (int k = 0;k < g[i].size();k++){
				if (j - w[ g[i][k] ] >= 0){
					dp[i%2][j] = max( dp[i%2][j] , dp[(i-1)%2][j - w[ g[i][k] ]] + b[ g[i][k]]);
					sb += b[g[i][k]]; sw += w[g[i][k]];
				}
			}
			if (j - sw >= 0) dp[i%2][j] = max( dp[i%2][j] , dp[(i-1)%2][j - sw] + sb);
		}
	}
	cout << dp[cnt%2][s] << '\n';
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e3+100;

int n , m , s;

int w[maxn] , b[maxn];

int dp[2][maxn];

int cnt;
vector <int> g[maxn] , CONN[maxn];

int v[maxn];

int main(){
	cin >> n >> m >> s;
	for (int i = 1;i <= n;i++) cin >> w[i];
	for (int i = 1;i <= n;i++) cin >> b[i];

	for (int i = 0;i < m;i++){
		int x,y; cin >> x >> y;
		CONN[x].push_back(y);
		CONN[y].push_back(x);
	}
	cnt = 0;
	for (int i = 1;i <= n;i++){
		if (v[i]) continue;
		queue <int> Q; Q.push(i);
		cnt ++;
		while (not Q.empty()){
			int act = Q.front(); Q.pop();
			v[act] = 1;
			g[cnt].push_back(act);
			for (int j = 0;j < CONN[act].size();j++){
				if (v[CONN[act][j]]) continue;
				//v[CONN[act][j]] = 1;
				Q.push(CONN[act][j]);
			}
		}
	}

	for (int i = 0;i <= s;i++) dp[0][i] = 0; // no items

	for (int i = 1;i <= cnt;i++){ // for each group
		for (int j = 0;j <= s;j++){ // for each weight
			dp[i%2][j] = dp[(i-1)%2][j]; // not using any item
			for (int k =0;k < g[i].size();k++){
				if (j - w[ g[i][k] ] >= 0){
					dp[i%2][j] = max( dp[i%2][j] , dp[(i-1)%2][j - w[ g[i][k] ]] + b[ g[i][k]]);
				}
			}
		}
	}

	cout << dp[cnt%2][s] << '\n';
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e3+100;

int n , m , s;

int w[maxn] , b[maxn];

int dp[maxn][maxn];

int cnt;
vector <int> g[maxn] , CONN[maxn];

int v[maxn];

int main(){
	scanf("%d%d%d",&n,&m,&s);
	for (int i = 1;i <= n;i++) scanf("%d",&w[i]);
	for (int i = 1;i <= n;i++) scanf("%d",&b[i]);
	for (int i = 0;i < m;i++){
		int x,y; scanf("%d%d",&x,&y);
		CONN[x].push_back(y);
		CONN[y].push_back(x);
	}
	cnt = 0;
	for (int i = 1;i <= n;i++){
		if (v[i]) continue;
		queue <int> Q; Q.push(i);
		cnt ++;
		while (not Q.empty()){
			int act = Q.front(); Q.pop();
			v[act] = 1;
			g[cnt].push_back(act);
			for (int j = 0;j < CONN[act].size();j++){
				if (v[CONN[act][j]]) continue;
				v[CONN[act][j]] = 1;
				Q.push(CONN[act][j]);
			}
		}
	}
	for (int i = 0;i <= s;i++) dp[0][i] = 0; // no items
	for (int i = 1;i <= cnt;i++){ // for each group
		for (int j = 0;j <= s;j++){ // for each weight
			dp[i][j] = dp[i-1][j]; // not using any item
			int tw = 0, tb = 0;
			for (int k = 0;k < g[i].size();k++){
				if (j - w[ g[i][k] ] >= 0){
					dp[i][j] = max( dp[i][j] , dp[i-1][j - w[ g[i][k] ]] + b[ g[i][k]]);
				}
				tw += w[ g[i][k] ];
				tb += b[ g[i][k] ];
			}
			if (j - tw >= 0) dp[i][j] = max(dp[i][j] , dp[i-1][j - tw] + tb);
		}
	}
	printf("%d\n",dp[cnt][s]);
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e3+100;

int n , m , s;

int w[maxn] , b[maxn];

int dp[2][maxn];

int cnt;
vector <int> g[maxn] , CONN[maxn];

int v[maxn];

int main(){
	cin >> n >> m >> s;
	for (int i = 1;i <= n;i++) cin >> w[i];
	for (int i = 1;i <= n;i++) cin >> b[i];

	for (int i = 0;i < m;i++){
		int x,y; cin >> x >> y;
		CONN[x].push_back(y);
		CONN[y].push_back(x);
	}
	cnt = 0;
	for (int i = 1;i <= n;i++){
		if (v[i]) continue;
		queue <int> Q; Q.push(i);
		cnt ++;
		while (not Q.empty()){
			int act = Q.front(); Q.pop();
			v[act] = 1;
			g[cnt].push_back(act);
			for (int j = 0;j < CONN[act].size();j++){
				if (v[CONN[act][j]]) continue;
				//v[CONN[act][j]] = 1;
				Q.push(CONN[act][j]);
			}
		}
	}

	for (int i = 0;i <= s;i++) dp[0][i] = 0; // no items
	for (int i = 1;i <= cnt;i++){ // for each group
		for (int j = 0;j <= s;j++){ // for each weight
			dp[i%2][j] = dp[(i-1)%2][j]; // not using any item
			int sb = 0 , sw = 0;
			for (int k =0;k < g[i].size();k++){
				if (j - w[ g[i][k] ] >= 0){
					dp[i%2][j] = max( dp[i%2][j] , dp[(i-1)%2][j - w[ g[i][k] ]] + b[ g[i][k]]);
					sb += b[g[i][k]]; sw += w[g[i][k]];
				}
			}
			if (j - sw >= 0) dp[i%2][j] = max( dp[i%2][j] , dp[(i-1)%2][j - sw] + sb);
		}
	}

	cout << dp[cnt%2][s] << '\n';
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 100005;
const int maxm = 100005;
const int maxk = 100005;

int main(){
	int n; scanf("%d",&n);
	printf("YES\n");
	for (int i = 0;i < n;i++){
		int x1 , y1 ,x2 , y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
		x1 += 1e9;
		y1 += 1e9;
		printf("%d\n",(x1%2)*2+y1%2+1);
	}
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e3+100;

int n , m , s;

int w[maxn] , b[maxn];

int dp[2][maxn];

int cnt;
vector <int> g[maxn] , CONN[maxn];

int v[maxn];

int main(){
	cin >> n >> m >> s;
	for (int i = 1;i <= n;i++) cin >> w[i];
	for (int i = 1;i <= n;i++) cin >> b[i];

	for (int i = 0;i < m;i++){
		int x,y; cin >> x >> y;
		CONN[x].push_back(y);
		CONN[y].push_back(x);
	}
	cnt = 0;
	for (int i = 1;i <= n;i++){
		if (v[i]) continue;
		queue <int> Q; Q.push(i);
		cnt ++;
		while (not Q.empty()){
			int act = Q.front(); Q.pop();
			v[act] = 1;
			g[cnt].push_back(act);
			for (int j = 0;j < CONN[act].size();j++){
				if (v[CONN[act][j]]) continue;
				//v[CONN[act][j]] = 1;
				Q.push(CONN[act][j]);
			}
		}
	}

	for (int i = 0;i <= s;i++) dp[0][i] = 0; // no items

	for (int i = 1;i <= cnt;i++){ // for each group
		for (int j = 0;j <= s;j++){ // for each weight
			dp[i%2][j] = dp[(i-1)%2][j]; // not using any item
			int tw = 0, tb = 0;
			for (int k =0;k < g[i].size();k++){
				if (j - w[ g[i][k] ] >= 0){
					dp[i%2][j] = max( dp[i%2][j] , dp[(i-1)%2][j - w[ g[i][k] ]] + b[ g[i][k]]);
				}
				tw += w[ g[i][k] ];
				tb += b[ g[i][k ]];
			}
			if (j - tw >= 0) dp[i%2][j] = max(dp[i%2][j] , dp[(i-1)%2][j - tw] + tb);
		}
	}

	cout << dp[cnt%2][s] << '\n';
}


#include <bits/stdc++.h>

using namespace std;

#define len(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define debug(x) cerr << #x << " is " << x << '\n';
#define bin(x,b) bitset<b> vb(x); cout << vb << '\n';

#if ( ( _WIN32 || __WIN32__ ) && __cplusplus < 201103L)
    #define lld "%I64d"
#else
    #define lld "%lld"
#endif
#define tmax(a,b,c) max((a),max((b),(c)))
#define cmax(a,b,c,d) max((a),(tmax(a,b,c)))

typedef long long ll;
typedef pair <int,int> pi;

const long double EPS = 1e-10;
const ll MOD = 1e9 + 7;
const ll INF = 1e18;
const long double PI = 3.1415926535897932384626433832795028841;

map <string ,int> ssol;
void checkAdd(string vs){ if (ssol.find(vs) != ssol.end()){ return; } ssol[vs] = 1; }

bool TST = 0;
ll powmod(ll a,ll b) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void Show(int *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }
void ShowLL(ll *QQ,int N){ if (not TST){ return; } for (int x = 0;x < N;x++){ cout << QQ[x]; if (x != N-1){ cout << ','; } } cout << '\n'; }

const int maxn = 1e4+100;

int n , m , s;

int w[maxn] , b[maxn];

int f[maxn][maxn];

int dp[maxn][maxn];

int cnt;
vector <int> g[maxn];

int main(){
	cin >> n >> m >> s;
	for (int i = 1;i <= n;i++) cin >> w[i];
	for (int i = 1;i <= n;i++) cin >> b[i];
	for (int i = 0;i < m;i++){
		int x,y; cin >> x >> y;
		f[x][y] = 1;
		f[y][x] = 1;
	}
	cnt = 1;
	for (int i = 1;i <= n;i++){
		if (i != 1 and not f[i][i-1]) cnt ++;
		g[cnt].push_back(i);
	}

	for (int i = 0;i <= s;i++) dp[0][i] = 0; // no items
	for (int i = 1;i <= cnt;i++){ // for each group
		for (int j = 0;j <= s;j++){ // for each weight
			dp[i][j] = dp[i-1][j]; // not using any item
			int sb = 0 , sw = 0;
			for (int k = 0;k < g[i].size();k++){
				if (j - w[ g[i][k] ] >= 0){
					dp[i][j] = max( dp[i][j] , dp[i-1][j - w[ g[i][k] ]] + b[ g[i][k]]);
					sb += b[g[i][k]]; sw += w[g[i][k]];
				}
			}
			if (j - sw >= 0) dp[i][j] = max( dp[i][j] , dp[i-1][j - sw] + sb);
		}
	}
	cout << dp[cnt][s] << '\n';
}


                                    /* Survive. Live. Win. Conquer.*/

#include<bits/stdc++.h>
using namespace std;
typedef long long LL ;
#define get(a) for( int i = 0; i < n; i++) sf("%d", &a[i]) ;
#define bug printf("TRUST\n");
#define pf printf
#define sf scanf
#define lp(i, n) for(int i = 0; i < n; i++)
#define rlp(n, i) for(int i = n - 1; i >= 0; i--)
#define bye vector<LL>
#define pb push_back
#define r0 return 0
#define ff first
#define ss second
#define mp make_pair
#define pii pair <int, int>
#define mod 1000000007
#define nod 200003
#define maxn 1002
void func(void)
{
        freopen("input.c","r",stdin);
        freopen("output.c","w",stdout);
}
int num = 0;
int vis[1003];
vector <int> a[1002], fri[1002];
LL dp[maxn][maxn];
void dfs(int x){
    vis[x] = 1;
    fri[num].pb(x);
    for(int i = a[x].size() - 1; i >= 0; i--){
        int v = a[x][i];
        if(!vis[v])
            dfs(v);
    }
}
LL weight, wei[1002], b[1002];
LL dpp(int i, LL w){
    //if(i == num)
      //  return 0;
    if(w > weight)
        return -100000000000000000;
    if(i == num)
        return 0;

    if(dp[i][w] != -1)
        return dp[i][w];
    LL ans = dpp(i + 1, w);
    int sz = fri[i].size();
    for(int k = 0; k < sz - 2; k++){
        int v = fri[i][k];
        ans = max(ans, dpp(i + 1, w + wei[v]) + b[v]);
    }
    LL v = fri[i][sz - 2];
    LL bea = fri[i][sz - 1];
    ans = max(ans, dpp(i + 1, w + v) + bea);
    return dp[i][w] = ans;
}

int main(){
//    ios_base::sync_with_stdio(0); cin.tie(0);
    LL n, q, i,j = 0, temp, t, k, ans = 0, sum = 0, cnt = 0, m, fg = 0, x, y, mx = 0, mx1 = 0, mn = 10000000000000000, mn1 = 10000000000000000;
    cin >> n >> m >> weight;
    for(int i = 1; i <= n; i++)
        cin >> wei[i];
    for(int i = 1; i <= n; i++)
        cin >> b[i];
    for(int i = 0; i < m; i++){
        cin >> x >> y;
        a[x].pb(y);
        a[y].pb(x);
    }
    memset(dp, -1, sizeof(dp));

    for(int i = 1; i <= n; i++){
        if(!vis[i]){
            dfs(i);
            sum = 0;
            ans = 0;
            for(int i = fri[num].size() - 1; i >= 0; i--){
                int v = fri[num][i];
                sum += wei[v];
                ans += b[v];
            }
            fri[num].pb(sum);
            fri[num].pb(ans);
            num++;
        }
    }

  /*  for(int i = 0; i < num; i++){
        cout << " " << i << " --> ";
        for(int j = 0; j < fri[i].size(); j++){
            cout << fri[i][j] << " ";
        }
        cout << endl;
    }*/

    cout << max((LL)0, dpp(0, 0)) << endl;
    r0;
}


                                    /* Survive. Live. Win. Conquer.*/

#include<bits/stdc++.h>
using namespace std;
typedef long long LL ;
#define get(a) for( int i = 0; i < n; i++) sf("%d", &a[i]) ;
#define bug printf("TRUST\n");
#define pf printf
#define sf scanf
#define lp(i, n) for(int i = 0; i < n; i++)
#define rlp(n, i) for(int i = n - 1; i >= 0; i--)
#define bye vector<LL>
#define pb push_back
#define r0 return 0
#define ff first
#define ss second
#define mp make_pair
#define pii pair <int, int>
#define mod 1000000007
#define nod 200003
#define maxn 1002
void func(void)
{
        freopen("input.c","r",stdin);
        freopen("output.c","w",stdout);
}
int num = 0;
int vis[1003];
vector <int> a[1002], fri[1002];
LL dp[maxn][maxn];
void dfs(int x){
    vis[x] = 1;
    fri[num].pb(x);
    for(int i = a[x].size() - 1; i >= 0; i--){
        int v = a[x][i];
        if(!vis[v])
            dfs(v);
    }
}
LL weight, wei[1002], b[1002];
LL dpp(int i, LL w){
    //if(i == num)
      //  return 0;
    if(w > weight)
        return -100000000000000000;
    if(i == num)
        return 0;

    if(dp[i][w] != -1)
        return dp[i][w];
    LL ans = dpp(i + 1, w);
    int sz = fri[i].size();
    for(int k = 0; k < sz - 2; k++){
        int v = fri[i][k];
        ans = max(ans, dpp(i + 1, w + wei[v]) + b[v]);
    }
    LL v = fri[i][sz - 2];
    LL bea = fri[i][sz - 1];
    ans = max(ans, dpp(i + 1, w + v) + bea);
    return dp[i][w] = ans;
}

int main(){
//    ios_base::sync_with_stdio(0); cin.tie(0);
    LL n, q, i,j = 0, temp, t, k, ans = 0, sum = 0, cnt = 0, m, fg = 0, x, y, mx = 0, mx1 = 0, mn = 10000000000000000, mn1 = 10000000000000000;
    cin >> n >> m >> weight;
    for(int i = 1; i <= n; i++)
        sf("%lld", &wei[i]);
    for(int i = 1; i <= n; i++)
        sf("%lld", &b[i]);
    for(int i = 0; i < m; i++){
        sf("%lld%lld", &x, &y);
        a[x].pb(y);
        a[y].pb(x);
    }
    memset(dp, -1, sizeof(dp));

    for(int i = 1; i <= n; i++){
        if(!vis[i]){
            dfs(i);
            sum = 0;
            ans = 0;
            for(int i = fri[num].size() - 1; i >= 0; i--){
                int v = fri[num][i];
                sum += wei[v];
                ans += b[v];
            }
            fri[num].pb(sum);
            fri[num].pb(ans);
            num++;
        }
    }

  /*  for(int i = 0; i < num; i++){
        cout << " " << i << " --> ";
        for(int j = 0; j < fri[i].size(); j++){
            cout << fri[i][j] << " ";
        }
        cout << endl;
    }*/

    cout << max((LL)0, dpp(0, 0)) << endl;
    r0;
}


                                    /* Survive. Live. Win. Conquer.*/

#include<bits/stdc++.h>
using namespace std;
typedef long long LL ;
#define get(a) for( int i = 0; i < n; i++) sf("%d", &a[i]) ;
#define bug printf("TRUST\n");
#define pf printf
#define sf scanf
#define lp(i, n) for(int i = 0; i < n; i++)
#define rlp(n, i) for(int i = n - 1; i >= 0; i--)
#define bye vector<LL>
#define pb push_back
#define r0 return 0
#define ff first
#define ss second
#define mp make_pair
#define pii pair <int, int>
#define mod 1000000007
#define nod 200003
#define maxn 1002
void func(void)
{
        freopen("input.c","r",stdin);
        freopen("output.c","w",stdout);
}
int num = 0;
int vis[1003];
vector <int> a[1002], fri[1002];
int dp[maxn][maxn];
void dfs(int x){
    vis[x] = 1;
    fri[num].pb(x);
    for(int i = a[x].size() - 1; i >= 0; i--){
        int v = a[x][i];
        if(!vis[v])
            dfs(v);
    }
}
int weight, wei[1002], b[1002];
int dpp(int i, int w){
    //if(i == num)
      //  return 0;
    if(w > weight)
        return -100000000;
    if(i == num)
        return 0;

    if(dp[i][w] != -1)
        return dp[i][w];
    int ans = dpp(i + 1, w);
    int sz = fri[i].size();
    for(int k = 0; k < sz - 2; k++){
        int v = fri[i][k];
        ans = max(ans, dpp(i + 1, w + wei[v]) + b[v]);
    }
    int v = fri[i][sz - 2];
    int bea = fri[i][sz - 1];
    ans = max(ans, dpp(i + 1, w + v) + bea);
    return dp[i][w] = ans;
}

int main(){
//    ios_base::sync_with_stdio(0); cin.tie(0);
    LL n, q, i,j = 0, temp, t, k, ans = 0, sum = 0, cnt = 0, m, fg = 0, x, y, mx = 0, mx1 = 0, mn = 10000000000000000, mn1 = 10000000000000000;
    cin >> n >> m >> weight;
    for(int i = 1; i <= n; i++)
        cin >> wei[i];
    for(int i = 1; i <= n; i++)
        cin >> b[i];
    for(int i = 0; i < m; i++){
        cin >> x >> y;
        a[x].pb(y);
        a[y].pb(x);
    }
    memset(dp, -1, sizeof(dp));

    for(int i = 1; i <= n; i++){
        if(!vis[i]){
            dfs(i);
            sum = 0;
            ans = 0;
            for(int i = fri[num].size() - 1; i >= 0; i--){
                int v = fri[num][i];
                sum += wei[v];
                ans += b[v];
            }
            fri[num].pb(sum);
            fri[num].pb(ans);
            num++;
        }
    }

  /*  for(int i = 0; i < num; i++){
        cout << " " << i << " --> ";
        for(int j = 0; j < fri[i].size(); j++){
            cout << fri[i][j] << " ";
        }
        cout << endl;
    }*/

    cout << max(0, dpp(0, 0)) << endl;
    r0;
}


                                    /* Survive. Live. Win. Conquer.*/

#include<bits/stdc++.h>
using namespace std;
typedef long long LL ;
#define get(a) for( int i = 0; i < n; i++) sf("%d", &a[i]) ;
#define bug printf("TRUST\n");
#define pf printf
#define sf scanf
#define lp(i, n) for(int i = 0; i < n; i++)
#define rlp(n, i) for(int i = n - 1; i >= 0; i--)
#define bye vector<LL>
#define pb push_back
#define r0 return 0
#define ff first
#define ss second
#define mp make_pair
#define pii pair <int, int>
#define mod 1000000007
#define nod 200003
#define maxn 1002
void func(void)
{
        freopen("input.c","r",stdin);
        freopen("output.c","w",stdout);
}
LL num = 0;
LL vis[1003];
vector <LL> a[1002], fri[1002];
LL dp[maxn][maxn];
void dfs(LL x){
    vis[x] = 1;
    fri[num].pb(x);
    for(LL i = a[x].size() - 1; i >= 0; i--){
        LL v = a[x][i];
        if(!vis[v])
            dfs(v);
    }
}
LL weight, wei[1002], b[1002];
LL dpp(LL i, LL w){
    //if(i == num)
      //  return 0;
    if(w > weight)
        return -100000000;
    if(i == num)
        return 0;

    if(dp[i][w] != -1)
        return dp[i][w];
    LL ans = dpp(i + 1, w);
    LL sz = fri[i].size();
    for(LL k = 0; k < sz - 2; k++){
        LL v = fri[i][k];
        ans = max(ans, dpp(i + 1, w + wei[v]) + b[v]);
    }
    LL v = fri[i][sz - 2];
    LL bea = fri[i][sz - 1];
    ans = max(ans, dpp(i + 1, w + v) + bea);
    return dp[i][w] = ans;
}

int main(){
//    ios_base::sync_with_stdio(0); cin.tie(0);
    LL n, q, i,j = 0, temp, t, k, ans = 0, sum = 0, cnt = 0, m, fg = 0, x, y, mx = 0, mx1 = 0, mn = 10000000000000000, mn1 = 10000000000000000;
    cin >> n >> m >> weight;
    for(LL i = 1; i <= n; i++)
        cin >> wei[i];
    for(LL i = 1; i <= n; i++)
        cin >> b[i];
    for(LL i = 0; i < m; i++){
        cin >> x >> y;
        a[x].pb(y);
        a[y].pb(x);
    }
    memset(dp, -1, sizeof(dp));

    for(LL i = 1; i <= n; i++){
        if(!vis[i]){
            dfs(i);
            sum = 0;
            ans = 0;
            for(LL i = fri[num].size() - 1; i >= 0; i--){
                LL v = fri[num][i];
                sum += wei[v];
                ans += b[v];
            }
            fri[num].pb(sum);
            fri[num].pb(ans);
            num++;
        }
    }

  /*  for(LL i = 0; i < num; i++){
        cout << " " << i << " --> ";
        for(LL j = 0; j < fri[i].size(); j++){
            cout << fri[i][j] << " ";
        }
        cout << endl;
    }*/

    cout << max((LL)0, dpp(0, 0)) << endl;
    r0;
}