#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = (int)1e5 + 1, seed = 27, mod1 = (int)1e9 + 7, mod2 = (int)1e9 + 9;
int n, m, q, len[maxn], rep[maxn], ord[maxn], ans[maxn];
char buf[maxn], pat[maxn];
LL pw[maxn], h[maxn], val[maxn];
pair<LL, int> seq[maxn];
int main() {
	scanf("%s%d", buf, &q);
	n = strlen(buf);
	pw[0] = 1LL << 30 | 1;
	for(int i = 0; i < n; ++i) {
		int ch = buf[i] - 'a' + 1;
		LL h1 = h[i] >> 30, h2 = h[i] & ((1 << 30) - 1);
		h1 = (h1 * seed + ch) % mod1;
		h2 = (h2 * seed + ch) % mod2;
		h[i + 1] = h1 << 30 | h2;
		LL p1 = pw[i] >> 30, p2 = pw[i] & ((1 << 30) - 1);
		p1 = p1 * seed % mod1;
		p2 = p2 * seed % mod2;
		pw[i + 1] = p1 << 30 | p2;
	}
	for(int i = 0; i < q; ++i) {
		scanf("%d%s", rep + i, pat);
		len[i] = strlen(pat);
		LL h1 = 0, h2 = 0;
		for(int j = 0; j < len[i]; ++j) {
			int ch = pat[j] - 'a' + 1;
			h1 = (h1 * seed + ch) % mod1;
			h2 = (h2 * seed + ch) % mod2;
		}
		val[i] = h1 << 30 | h2;
		ord[i] = i;
	}
	sort(ord, ord + q, [&](int const &u, int const &v) {
		return len[u] < len[v];
	});
	for(int o = 0, stp = 0; o < q; ++o) {
		int i = ord[o];
		int &res = ans[i] = maxn;
		if(stp != len[i]) {
			stp = len[i];
			m = 0;
			LL p1 = mod1 - (pw[stp] >> 30), p2 = mod2 - (pw[stp] & ((1 << 30) - 1));
			for(int j = 0, k = j + stp; k <= n; ++j, ++k) {
				LL h1 = h[j] >> 30, h2 = h[j] & ((1 << 30) - 1);
				LL h3 = h[k] >> 30, h4 = h[k] & ((1 << 30) - 1);
				h1 = (h1 * p1 + h3) % mod1;
				h2 = (h2 * p2 + h4) % mod2;
				seq[m++] = make_pair(h1 << 30 | h2, j);
			}
			sort(seq, seq + m);
		}
		int L = lower_bound(seq, seq + m, make_pair(val[i], 0)) - seq;
		int R = lower_bound(seq, seq + m, make_pair(val[i] + 1, 0)) - seq;
		for(int j = L, k = j + rep[i] - 1; k < R; ++j, ++k)
			res = min(res, seq[k].second - seq[j].second + len[i]);
	}
	for(int i = 0; i < q; ++i)
		printf("%d\n", ans[i] < maxn ? ans[i] : -1);
	return 0;
}


#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
#define next Nxt
#define last Lst
#define gc getchar
//#define int long long
const int N=2e5+5;
int n,m,cnt=1,pos[N],b[N],nxt[N],a[N],len[N],top[N],ch[N][26];
vector<int>g[N],G[N];
char s[N],ss[N];
//char buf[1<<21],*p1=buf,*p2=buf;
//inline int gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
inline int read()
{
    int ret=0,f=0;char c=gc();
    while(!isdigit(c)){if(c=='-')f=1;c=gc();}
    while(isdigit(c)){ret=ret*10+c-48;c=gc();}
    if(f)return -ret;return ret;
}
void insert(char *s,int id)
{
	int n=strlen(s+1);
	int u=1;
	for(int i=1;i<=n;i++)
	{
		int c=s[i]-'a';
		if(!ch[u][c])ch[u][c]=++cnt;
		u=ch[u][c];
	}
	pos[id]=u;
	b[u]=1;
}
void build()
{
	queue<int>q;
	q.push(1);
	while(!q.empty())
	{
		int u=q.front();q.pop();
		for(int i=0;i<26;i++)
		{
			if(ch[u][i])
			{
				nxt[ch[u][i]]=ch[nxt[u]][i];
				q.push(ch[u][i]);
			}
			else ch[u][i]=ch[nxt[u]][i];
		}
	}
}
void dfs(int u,int fa)
{
	if(b[fa])top[u]=fa;
	else top[u]=top[fa];
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i];
		dfs(v,u);
	}
}
void work(char *s)
{
	int n=strlen(s+1);
	int u=1;
	for(int i=1;i<=n;i++)
	{
		int c=s[i]-'a';
		int x=ch[u][c];
		while(x>1)
		{
			if(b[x])g[x].push_back(i);
			x=top[x];
		}
		u=ch[u][c];
	}
}
signed main()
{
	for(int i=0;i<26;i++)ch[0][i]=1;
	scanf("%s",s+1);
	n=read();
	for(int i=1;i<=n;i++)
	{
		a[i]=read();
		scanf("%s",ss+1);
		len[i]=strlen(ss+1);
		insert(ss,i);
	}
	build();
	for(int i=2;i<=cnt;i++)G[nxt[i]].push_back(i);
	dfs(1,0);
	work(s);
	for(int i=1;i<=n;i++)
	{
		if(g[pos[i]].size()<a[i]){puts("-1");continue;}
		int res=1e9;
		for(int j=0;j<g[pos[i]].size()-a[i]+1;j++)
		{
			int x=j+a[i]-1;
			res=min(res,g[pos[i]][x]-g[pos[i]][j]+1);
		}
		printf("%d\n",res+len[i]-1);
	}
	return 0;
}


#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define n_max 10001
#define inf 1000000007
vector<int> comp[n_max], graph[n_max];
vector<bool> used(n_max,0);
void DFS(int v, int c){
    comp[c].push_back(v);
    used[v] = 1;
    for(auto to:graph[v])
        if(!used[to]) DFS(to,c);
}
ll dp[1001][1001];
int main()
{
    //ios_base::sync_with_stdio(); cin.tie();cout.tie();
    int n, m, k;
    ll W, a;
    scanf("%d %d %I64d", &n, &m, &W);
    vector<ll> w(n+1), b(n+1);
    for(int i = 1; i <= n; i++)
        scanf("%I64d", &w[i]);
    for(int i = 1; i <= n; i++)
        scanf("%I64d", &b[i]);
    while(m--){
        scanf("%d %d", &a, &k);
        graph[a].push_back(k);
        graph[k].push_back(a);
    }
    int c = 0;
    for(int i = 1; i <= n; i++){
        if(!used[i])
            DFS(i,c++);
    }
    a = 0, k = 0;
    for(auto v:comp[0]){
        if(w[v] <= W) dp[0][w[v]] = b[v];
        a += w[v], k += b[v];
    }
    if(a <= W) dp[0][a] = k;
    for(int i = 0; i < c; i++)
        for(int j = 0; j <= W; j++){
            dp[i+1][j] = max(dp[i][j], dp[i+1][j]);
            ll sum_w = 0, sum_b = 0;
            for(auto v:comp[i+1]){
                sum_b += b[v], sum_w += w[v];
                dp[i+1][w[v]] = max(dp[i][0] + b[v], dp[i+1][w[v]]);
                if(j + w[v] > W) continue;
                dp[i+1][w[v]+j] = max(dp[i][j] + b[v], dp[i+1][w[v]+j]);
               // cout << dp[i][j] << " -> " << b[v] << ' ' << dp[i+1][j+w[v]] << " w[v] = " << w[v] << "\n";
            }
            if(j + sum_w <= W)
                dp[i+1][sum_w+j] = max(dp[i][j] + sum_b, dp[i+1][sum_w+j]);
            if(sum_w <= W) dp[i+1][sum_w] = max(dp[i][0] + sum_b, dp[i+1][sum_w]);
        }
    ll ans = 0;
    for(int i = 0; i <= W; i++)
        ans = max(ans, dp[c][i]);
    printf("%I64d", ans);

    return 0;
}


#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define n_max 10001
#define inf 1000000007
vector<int> comp[n_max], graph[n_max];
vector<bool> used(n_max,0);
void DFS(int v, int c){
    comp[c].push_back(v);
    used[v] = 1;
    for(auto to:graph[v])
        if(!used[to]) DFS(to,c);
}
ll dp[1001][1001];
int main()
{
    //ios_base::sync_with_stdio(); cin.tie();cout.tie();
    int n, m, k;
    ll W, a;
    scanf("%d %d %I64d", &n, &m, &W);
    vector<ll> w(n+1), b(n+1);
    for(int i = 1; i <= n; i++)
        scanf("%I64d", &w[i]);
    for(int i = 1; i <= n; i++)
        scanf("%I64d", &b[i]);
    while(m--){
        scanf("%d %d", &a, &k);
        graph[a].push_back(k);
        graph[k].push_back(a);
    }
    int c = 0;
    for(int i = 1; i <= n; i++){
        if(!used[i])
            DFS(i,c++);
    }
    a = 0, k = 0;
    for(auto v:comp[0]){
        if(w[v] <= W) dp[0][w[v]] = max(b[v], dp[0][w[v]]);
        a += w[v], k += b[v];
    }
    if(a <= W) dp[0][a] = max(ll(k), dp[0][a]);
    for(int i = 0; i < c-1; i++)
        for(int j = 0; j <= W; j++){
            dp[i+1][j] = max(dp[i][j], dp[i+1][j]);
            ll sum_w = 0, sum_b = 0;
            for(auto v:comp[i+1]){
                sum_b += b[v], sum_w += w[v];
                dp[i+1][w[v]] = max(dp[i][0] + b[v], dp[i+1][w[v]]);
                if(j + w[v] > W) continue;
                dp[i+1][w[v]+j] = max(dp[i][j] + b[v], dp[i+1][w[v]+j]);
               // cout << dp[i][j] << " -> " << b[v] << ' ' << dp[i+1][j+w[v]] << " w[v] = " << w[v] << "\n";
            }
            if(j + sum_w <= W)
                dp[i+1][sum_w+j] = max(dp[i][j] + sum_b, dp[i+1][sum_w+j]);
            if(sum_w <= W) dp[i+1][sum_w] = max(dp[i][0] + sum_b, dp[i+1][sum_w]);
        }
    ll ans = 0;
    for(int i = 0; i <= W; i++)
        ans = max(ans, dp[c-1][i]);
    printf("%I64d", ans);

    return 0;
}


#include <bits/stdc++.h>
#define UNVISITED -1
#define POSINF 1 << 25
#define NEGINF -1 << 25
#define _ ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0), cout.precision(15);
using namespace std;

typedef long long int64;
typedef pair<int, int> ii;

vector<int> visited;
vector< vector<int> > AdjList, groupW, groupB;

void dfs(int u, int groupIdx){
    visited[u] = groupIdx;
    for(auto v : AdjList[u])
        if(visited[v] == UNVISITED)
            dfs(v, groupIdx);
}

int main(){ _
    int n, m, W;    cin >> n >> m >> W;
    visited.assign(n, UNVISITED);
    AdjList.assign(n, vector<int> (0));
    vector<int> weight(n, 0), beauty(n, 0);
    for(int i = 0; i < n; ++i)  cin >> weight[i];
    for(int i = 0; i < n; ++i)  cin >> beauty[i];
    for(int i = 0; i < m; ++i){
        int u, v;   cin >> u >> v;
        --u, --v;
        AdjList[u].push_back(v);
        AdjList[v].push_back(u);
    }

    int groupIdx = 0;
    for(int i = 0; i < n; ++i){
        if(visited[i] != UNVISITED)  continue;
        dfs(i, groupIdx);
        groupW.push_back(vector<int> (0));
        groupB.push_back(vector<int> (0));
        int totalW = 0, totalB = 0;
        for(int j = 0; j < n; ++j){
            if(visited[j] == groupIdx){
                totalW += weight[j];
                totalB += beauty[j];
                groupW[groupIdx].push_back(weight[j]);
                groupB[groupIdx].push_back(beauty[j]);
            }
        }
        groupW[groupIdx].push_back(totalW);
        groupB[groupIdx].push_back(totalB);
        // cout << "group " << groupIdx << "\tweight: " << totalW << "\tBeauty: " << totalB << endl;
        ++groupIdx;
    }

    // knapsack
    // vector<int> table(W + 1, 0);
    // for(int w = W; w >= 0; --w){
    //     for(int i = 0; i < groupIdx; ++i){
    //         for(int k = 0; k < groupW[i].size(); ++k){
    //             if(w < groupW[i][k])    continue;
    //             table[w] = max(table[w], table[w - groupW[i][k]] + groupB[i][k]);
    //         }
    //     }
    // }
    // int ans = 0;
    // for(auto ele : table)   ans = max(ans, ele);
    // cout << ans << endl;

    int pre = 0, cur = 1;
    vector< vector<int> > table(2, vector<int> (W + 1, 0));
    for(int i = 0; i < groupIdx; ++i){
        table[cur].assign(W + 1, 0);
        for(int j = 0; j < groupW[i].size(); ++j){
            for(int k = 0; k <= W; ++k){
                if(k < groupW[i][j])   continue;
                table[cur][k] = max(table[cur][k],
                    max(table[pre][k], table[pre][k - groupW[i][j]] + groupB[i][j]));
            }
        }
        pre = 1 - pre, cur = 1 - cur;
    }
    int ans = 0;
    for(auto ele : table[pre])  ans = max(ele, ans);
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>
#define UNVISITED -1
#define POSINF 1 << 25
#define NEGINF -1 << 25
#define _ ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0), cout.precision(15);
using namespace std;

typedef long long int64;
typedef pair<int, int> ii;

vector<int> visited;
vector< vector<int> > AdjList, groupW, groupB;

void dfs(int u, int groupIdx){
    visited[u] = groupIdx;
    for(auto v : AdjList[u])
        if(visited[v] == UNVISITED)
            dfs(v, groupIdx);
}

int main(){ _
    int n, m, W;    cin >> n >> m >> W;
    visited.assign(n, UNVISITED);
    AdjList.assign(n, vector<int> (0));
    vector<int> weight(n, 0), beauty(n, 0);
    for(int i = 0; i < n; ++i)  cin >> weight[i];
    for(int i = 0; i < n; ++i)  cin >> beauty[i];
    for(int i = 0; i < m; ++i){
        int u, v;   cin >> u >> v;
        --u, --v;
        AdjList[u].push_back(v);
        AdjList[v].push_back(u);
    }

    int groupIdx = 0;
    for(int i = 0; i < n; ++i){
        if(visited[i] != UNVISITED)  continue;
        dfs(i, groupIdx);
        groupW.push_back(vector<int> (0));
        groupB.push_back(vector<int> (0));
        int totalW = 0, totalB = 0;
        for(int j = 0; j < n; ++j){
            if(visited[j] == groupIdx){
                totalW += weight[j];
                totalB += beauty[j];
                groupW[groupIdx].push_back(weight[j]);
                groupB[groupIdx].push_back(beauty[j]);
            }
        }
        groupW[groupIdx].push_back(totalW);
        groupB[groupIdx].push_back(totalB);
        // cout << "group " << groupIdx << "\tweight: " << totalW << "\tBeauty: " << totalB << endl;
        ++groupIdx;
    }

    // knapsack
    int pre = 0, cur = 1;
    vector< vector<int> > table(2, vector<int> (W + 1, 0));
    for(int i = 0; i < groupIdx; ++i){
        for(int j = 0; j < groupW[i].size(); ++j){
            for(int k = 0; k <= W; ++k){
                if(k < groupW[i][j])   continue;
                table[cur][k] = max(table[cur][k],
                    max(table[pre][k], table[pre][k - groupW[i][j]] + groupB[i][j]));
            }
        }
        pre = 1 - pre, cur = 1 - cur;
        table[cur].assign(W + 1, 0);
    }
    cout << table[pre][W] << endl;
    return 0;
}


#include <bits/stdc++.h>
#define UNVISITED -1
#define POSINF 1 << 25
#define NEGINF -1 << 25
#define _ ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0), cout.precision(15);
using namespace std;

typedef long long int64;
typedef pair<int, int> ii;

vector<int> visited;
vector< vector<int> > AdjList, groupW, groupB;

void dfs(int u, int groupIdx){
    visited[u] = groupIdx;
    for(auto v : AdjList[u])
        if(visited[v] == UNVISITED)
            dfs(v, groupIdx);
}

int main(){ _
    int n, m, W;    cin >> n >> m >> W;
    visited.assign(n, UNVISITED);
    AdjList.assign(n, vector<int> (0));
    vector<int> weight(n, 0), beauty(n, 0);
    for(int i = 0; i < n; ++i)  cin >> weight[i];
    for(int i = 0; i < n; ++i)  cin >> beauty[i];
    for(int i = 0; i < m; ++i){
        int u, v;   cin >> u >> v;
        --u, --v;
        AdjList[u].push_back(v);
        AdjList[v].push_back(u);
    }

    int groupIdx = 0;
    for(int i = 0; i < n; ++i){
        if(visited[i] != UNVISITED)  continue;
        dfs(i, groupIdx);
        groupW.push_back(vector<int> (0));
        groupB.push_back(vector<int> (0));
        int totalW = 0, totalB = 0;
        for(int j = 0; j < n; ++j){
            if(visited[j] == groupIdx){
                totalW += weight[j];
                totalB += beauty[j];
                groupW[groupIdx].push_back(weight[j]);
                groupB[groupIdx].push_back(beauty[j]);
            }
        }
        groupW[groupIdx].push_back(totalW);
        groupB[groupIdx].push_back(totalB);
        // cout << "group " << groupIdx << "\tweight: " << totalW << "\tBeauty: " << totalB << endl;
        ++groupIdx;
    }

    // vector<int> table(W + 1, 0);
    // for(int i = 0; i < groupIdx; ++i){
    //     for(int w = W; w >= 0; --w){
    //         for(int k = 0; k < groupW[i].size(); ++k){
    //             if(w < groupW[i][k])    continue;
    //             table[w] = max(table[w], table[w - groupW[i][k]] + groupB[i][k]);
    //         }
    //     }
    // }
    // int ans = 0;
    // for(auto ele : table)   ans = max(ans, ele);
    // cout << ans << endl;

    int pre = 0, cur = 1;
    vector< vector<int> > table(2, vector<int> (W + 1, 0));
    for(int i = 0; i < groupIdx; ++i){
        table[cur].assign(W + 1, 0);
        for(int w = W; w >= 0; --w){
            table[cur][w] = max(table[cur][w], table[pre][w]);
            for(int k = 0; k < groupW[i].size(); ++i){
                if(w < groupW[i][k])    continue;
                table[cur][w] = max(table[cur][w], table[pre][w - groupW[i][k] + groupB[i][k]);
            }
        }
        pre = 1 - pre, cur = 1 - cur;
    }
    int ans = 0;
    for(auto ele : table[pre])  ans = max(ele, ans);
    cout << ans << endl;

    // int pre = 0, cur = 1;
    // vector< vector<int> > table(2, vector<int> (W + 1, 0));
    // for(int i = 0; i < groupIdx; ++i){
    //     table[cur].assign(W + 1, 0);
    //     for(int w = 0; w <= W; ++w){
    //         for(int j = 0; j < groupW[i].size(); ++j){
    //             if(w < groupW[i][j])   continue;
    //             table[cur][w] = max(table[cur][w],
    //                 max(table[pre][w], table[pre][w - groupW[i][j]] + groupB[i][j]));
    //         }
    //     }
    //     pre = 1 - pre, cur = 1 - cur;
    // }
    // int ans = 0;
    // for(auto ele : table[pre])  ans = max(ele, ans);
    // cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>
#define UNVISITED -1
#define POSINF 1 << 25
#define NEGINF -1 << 25
#define _ ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0), cout.precision(15);
using namespace std;

typedef long long int64;
typedef pair<int, int> ii;

vector<int> visited;
vector< vector<int> > AdjList, groupW, groupB;

void dfs(int u, int groupIdx){
    visited[u] = groupIdx;
    for(auto v : AdjList[u])
        if(visited[v] == UNVISITED)
            dfs(v, groupIdx);
}

int main(){ _
    int n, m, W;    cin >> n >> m >> W;
    visited.assign(n, UNVISITED);
    AdjList.assign(n, vector<int> (0));
    vector<int> weight(n, 0), beauty(n, 0);
    for(int i = 0; i < n; ++i)  cin >> weight[i];
    for(int i = 0; i < n; ++i)  cin >> beauty[i];
    for(int i = 0; i < m; ++i){
        int u, v;   cin >> u >> v;
        --u, --v;
        AdjList[u].push_back(v);
        AdjList[v].push_back(u);
    }

    int groupIdx = 0;
    for(int i = 0; i < n; ++i){
        if(visited[i] != UNVISITED)  continue;
        dfs(i, groupIdx);
        groupW.push_back(vector<int> (0));
        groupB.push_back(vector<int> (0));
        int totalW = 0, totalB = 0;
        for(int j = 0; j < n; ++j){
            if(visited[j] == groupIdx){
                totalW += weight[j];
                totalB += beauty[j];
                groupW[groupIdx].push_back(weight[j]);
                groupB[groupIdx].push_back(beauty[j]);
            }
        }
        groupW[groupIdx].push_back(totalW);
        groupB[groupIdx].push_back(totalB);
        // cout << "group " << groupIdx << "\tweight: " << totalW << "\tBeauty: " << totalB << endl;
        ++groupIdx;
    }

    // vector<int> table(W + 1, 0);
    // for(int i = 0; i < groupIdx; ++i){
    //     for(int w = W; w >= 0; --w){
    //         for(int k = 0; k < groupW[i].size(); ++k){
    //             if(w < groupW[i][k])    continue;
    //             table[w] = max(table[w], table[w - groupW[i][k]] + groupB[i][k]);
    //         }
    //     }
    // }
    // int ans = 0;
    // for(auto ele : table)   ans = max(ans, ele);
    // cout << ans << endl;

    int pre = 0, cur = 1;
    vector< vector<int> > table(2, vector<int> (W + 1, 0));
    for(int i = 0; i < groupIdx; ++i){
        table[cur].assign(W + 1, 0);
        for(int w = W; w >= 0; --w){
            table[cur][w] = max(table[cur][w], table[pre][w]);
            for(int k = 0; k < groupW[i].size(); ++i){
                if(w < groupW[i][k])    continue;
                table[cur][w] = max(table[cur][w], table[pre][w - groupW[i][k]] + groupB[i][k]);
            }
        }
        pre = 1 - pre, cur = 1 - cur;
    }
    int ans = 0;
    for(auto ele : table[pre])  ans = max(ele, ans);
    cout << ans << endl;

    // int pre = 0, cur = 1;
    // vector< vector<int> > table(2, vector<int> (W + 1, 0));
    // for(int i = 0; i < groupIdx; ++i){
    //     table[cur].assign(W + 1, 0);
    //     for(int w = 0; w <= W; ++w){
    //         for(int j = 0; j < groupW[i].size(); ++j){
    //             if(w < groupW[i][j])   continue;
    //             table[cur][w] = max(table[cur][w],
    //                 max(table[pre][w], table[pre][w - groupW[i][j]] + groupB[i][j]));
    //         }
    //     }
    //     pre = 1 - pre, cur = 1 - cur;
    // }
    // int ans = 0;
    // for(auto ele : table[pre])  ans = max(ele, ans);
    // cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>
#define UNVISITED -1
#define POSINF 1 << 25
#define NEGINF -1 << 25
#define _ ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0), cout.precision(15);
using namespace std;

typedef long long int64;
typedef pair<int, int> ii;

vector<int> visited;
vector< vector<int> > AdjList, groupW, groupB;

void dfs(int u, int groupIdx){
    visited[u] = groupIdx;
    for(auto v : AdjList[u])
        if(visited[v] == UNVISITED)
            dfs(v, groupIdx);
}

int main(){ _
    int n, m, W;    cin >> n >> m >> W;
    visited.assign(n, UNVISITED);
    AdjList.assign(n, vector<int> (0));
    vector<int> weight(n, 0), beauty(n, 0);
    for(int i = 0; i < n; ++i)  cin >> weight[i];
    for(int i = 0; i < n; ++i)  cin >> beauty[i];
    for(int i = 0; i < m; ++i){
        int u, v;   cin >> u >> v;
        --u, --v;
        AdjList[u].push_back(v);
        AdjList[v].push_back(u);
    }

    int groupIdx = 0;
    for(int i = 0; i < n; ++i){
        if(visited[i] != UNVISITED)  continue;
        dfs(i, groupIdx);
        groupW.push_back(vector<int> (0));
        groupB.push_back(vector<int> (0));
        int totalW = 0, totalB = 0;
        for(int j = 0; j < n; ++j){
            if(visited[j] == groupIdx){
                totalW += weight[j];
                totalB += beauty[j];
                groupW[groupIdx].push_back(weight[j]);
                groupB[groupIdx].push_back(beauty[j]);
            }
        }
        groupW[groupIdx].push_back(totalW);
        groupB[groupIdx].push_back(totalB);
        // cout << "group " << groupIdx << "\tweight: " << totalW << "\tBeauty: " << totalB << endl;
        ++groupIdx;
    }

    vector<int> table(maxW + 1, 0);
    for(int i = 0; i < groupIdx; ++i){
        for(int w = maxW; w >= 0; --w){
            for(int k = 0; k < groupW[i].size(); ++k){
                if(w < groupW[i][k])    continue;
                table[w] = max(table[w], table[w - groupW[i][k]] + groupB[i][k]);
            }
        }
    }
    int ans = 0;
    for(auto ele : table)   ans = max(ans, ele);
    cout << ans << endl;

    // int pre = 0, cur = 1;
    // vector< vector<int> > table(2, vector<int> (W + 1, 0));
    // for(int i = 0; i < groupIdx; ++i){
    //     table[cur].assign(W + 1, 0);
    //     for(int w = 0; w <= W; ++w){
    //         for(int j = 0; j < groupW[i].size(); ++j){
    //             if(w < groupW[i][j])   continue;
    //             table[cur][w] = max(table[cur][w],
    //                 max(table[pre][w], table[pre][w - groupW[i][j]] + groupB[i][j]));
    //         }
    //     }
    //     pre = 1 - pre, cur = 1 - cur;
    // }
    // int ans = 0;
    // for(auto ele : table[pre])  ans = max(ele, ans);
    // cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>
#define UNVISITED -1
#define POSINF 1 << 25
#define NEGINF -1 << 25
#define _ ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0), cout.precision(15);
using namespace std;

typedef long long int64;
typedef pair<int, int> ii;

vector<int> visited;
vector< vector<int> > AdjList, groupW, groupB;

void dfs(int u, int groupIdx){
    visited[u] = groupIdx;
    for(auto v : AdjList[u])
        if(visited[v] == UNVISITED)
            dfs(v, groupIdx);
}

int main(){ _
    int n, m, W;    cin >> n >> m >> W;
    visited.assign(n, UNVISITED);
    AdjList.assign(n, vector<int> (0));
    vector<int> weight(n, 0), beauty(n, 0);
    for(int i = 0; i < n; ++i)  cin >> weight[i];
    for(int i = 0; i < n; ++i)  cin >> beauty[i];
    for(int i = 0; i < m; ++i){
        int u, v;   cin >> u >> v;
        --u, --v;
        AdjList[u].push_back(v);
        AdjList[v].push_back(u);
    }

    int groupIdx = 0;
    for(int i = 0; i < n; ++i){
        if(visited[i] != UNVISITED)  continue;
        dfs(i, groupIdx);
        groupW.push_back(vector<int> (0));
        groupB.push_back(vector<int> (0));
        int totalW = 0, totalB = 0;
        for(int j = 0; j < n; ++j){
            if(visited[j] == groupIdx){
                totalW += weight[j];
                totalB += beauty[j];
                groupW[groupIdx].push_back(weight[j]);
                groupB[groupIdx].push_back(beauty[j]);
            }
        }
        groupW[groupIdx].push_back(totalW);
        groupB[groupIdx].push_back(totalB);
        // cout << "group " << groupIdx << "\tweight: " << totalW << "\tBeauty: " << totalB << endl;
        ++groupIdx;
    }

    // vector<int> table(W + 1, 0);
    // for(int i = 0; i < groupIdx; ++i){
    //     for(int w = W; w >= 0; --w){
    //         for(int k = 0; k < groupW[i].size(); ++k){
    //             if(w < groupW[i][k])    continue;
    //             table[w] = max(table[w], table[w - groupW[i][k]] + groupB[i][k]);
    //         }
    //     }
    // }
    // int ans = 0;
    // for(auto ele : table)   ans = max(ans, ele);
    // cout << ans << endl;

    vector< vector<int> > table(2, vector<int> (W + 1, 0));
    for(int i = 0; i < groupIdx; ++i){
        table[cur].assign(W + 1, 0);
        for(int w = W; w >= 0; --w){
            table[cur][w] = max(table[cur][w], table[pre][w]);
            for(int k = 0; k < groupW[i].size(); ++i){
                if(w < groupW[i][k])    continue;
                table[cur][w] = max(table[cur][w], table[pre][w - groupW[i][k] + groupB[i][k]);
            }
        }
        pre = 1 - pre, cur = 1 - cur;
    }
    int ans = 0;
    for(auto ele : table[pre])  ans = max(ele, ans);
    cout << ans << endl;

    // int pre = 0, cur = 1;
    // vector< vector<int> > table(2, vector<int> (W + 1, 0));
    // for(int i = 0; i < groupIdx; ++i){
    //     table[cur].assign(W + 1, 0);
    //     for(int w = 0; w <= W; ++w){
    //         for(int j = 0; j < groupW[i].size(); ++j){
    //             if(w < groupW[i][j])   continue;
    //             table[cur][w] = max(table[cur][w],
    //                 max(table[pre][w], table[pre][w - groupW[i][j]] + groupB[i][j]));
    //         }
    //     }
    //     pre = 1 - pre, cur = 1 - cur;
    // }
    // int ans = 0;
    // for(auto ele : table[pre])  ans = max(ele, ans);
    // cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>
#define UNVISITED -1
#define POSINF 1 << 25
#define NEGINF -1 << 25
#define _ ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0), cout.precision(15);
using namespace std;

typedef long long int64;
typedef pair<int, int> ii;

vector<int> visited;
vector< vector<int> > AdjList, groupW, groupB;

void dfs(int u, int groupIdx){
    visited[u] = groupIdx;
    for(auto v : AdjList[u])
        if(visited[v] == UNVISITED)
            dfs(v, groupIdx);
}

int main(){ _
    int n, m, W;    cin >> n >> m >> W;
    visited.assign(n, UNVISITED);
    AdjList.assign(n, vector<int> (0));
    vector<int> weight(n, 0), beauty(n, 0);
    for(int i = 0; i < n; ++i)  cin >> weight[i];
    for(int i = 0; i < n; ++i)  cin >> beauty[i];
    for(int i = 0; i < m; ++i){
        int u, v;   cin >> u >> v;
        --u, --v;
        AdjList[u].push_back(v);
        AdjList[v].push_back(u);
    }

    int groupIdx = 0;
    for(int i = 0; i < n; ++i){
        if(visited[i] != UNVISITED)  continue;
        dfs(i, groupIdx);
        groupW.push_back(vector<int> (0));
        groupB.push_back(vector<int> (0));
        int totalW = 0, totalB = 0;
        for(int j = 0; j < n; ++j){
            if(visited[j] == groupIdx){
                totalW += weight[j];
                totalB += beauty[j];
                groupW[groupIdx].push_back(weight[j]);
                groupB[groupIdx].push_back(beauty[j]);
            }
        }
        groupW[groupIdx].push_back(totalW);
        groupB[groupIdx].push_back(totalB);
        // cout << "group " << groupIdx << "\tweight: " << totalW << "\tBeauty: " << totalB << endl;
        ++groupIdx;
    }

    // vector<int> table(W + 1, 0);
    // for(int i = 0; i < groupIdx; ++i){
    //     for(int w = W; w >= 0; --w){
    //         for(int k = 0; k < groupW[i].size(); ++k){
    //             if(w < groupW[i][k])    continue;
    //             table[w] = max(table[w], table[w - groupW[i][k]] + groupB[i][k]);
    //         }
    //     }
    // }
    // int ans = 0;
    // for(auto ele : table)   ans = max(ans, ele);
    // cout << ans << endl;

    // int pre = 0, cur = 1;
    // vector< vector<int> > table(2, vector<int> (W + 1, 0));
    // for(int i = 0; i < groupIdx; ++i){
    //     table[cur].assign(W + 1, 0);
    //     for(int w = 0; w <= W; ++w){
    //         table[cur][w] = max(table[cur][w], table[pre][w]);
    //         for(int k = 0; k < groupW[i].size(); ++k){
    //             if(w < groupW[i][k])    continue;
    //             table[cur][w] = max(table[cur][w], table[pre][w - groupW[i][k]] + groupB[i][k]);
    //         }
    //     }
    //     pre = 1 - pre, cur = 1 - cur;
    // }
    // int ans = 0;
    // for(auto ele : table[pre])  ans = max(ele, ans);
    // cout << ans << endl;

    int pre = 0, cur = 1;
    vector< vector<int> > table(2, vector<int> (W + 1, 0));
    for(int i = 0; i < groupIdx; ++i){
        table[cur].assign(W + 1, 0);
        for(int w = 0; w <= W; ++w){
            // table[cur][w] = max(table[cur][w], table[pre][w]);
            for(int j = 0; j < groupW[i].size(); ++j){
                table[cur][w] = max(table[cur][w], table[pre][w]);
                if(w < groupW[i][j])   continue;
                // table[cur][w] = max(table[cur][w],
                    // max(table[pre][w], table[pre][w - groupW[i][j]] + groupB[i][j]));
                table[cur][w] = max(table[cur][w], table[pre][w - groupW[i][j]] + groupB[i][j]);
            }
        }
        pre = 1 - pre, cur = 1 - cur;
    }
    int ans = 0;
    for(auto ele : table[pre])  ans = max(ele, ans);
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>
#define UNVISITED -1
#define POSINF 1 << 25
#define NEGINF -1 << 25
#define _ ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0), cout.precision(15);
using namespace std;

typedef long long int64;
typedef pair<int, int> ii;

vector<int> visited;
vector< vector<int> > AdjList, groupW, groupB;

void dfs(int u, int groupIdx){
    visited[u] = groupIdx;
    for(auto v : AdjList[u])
        if(visited[v] == UNVISITED)
            dfs(v, groupIdx);
}

int main(){ _
    int n, m, W;    cin >> n >> m >> W;
    visited.assign(n, UNVISITED);
    AdjList.assign(n, vector<int> (0));
    vector<int> weight(n, 0), beauty(n, 0);
    for(int i = 0; i < n; ++i)  cin >> weight[i];
    for(int i = 0; i < n; ++i)  cin >> beauty[i];
    for(int i = 0; i < m; ++i){
        int u, v;   cin >> u >> v;
        --u, --v;
        AdjList[u].push_back(v);
        AdjList[v].push_back(u);
    }

    int groupIdx = 0;
    for(int i = 0; i < n; ++i){
        if(visited[i] != UNVISITED)  continue;
        dfs(i, groupIdx);
        groupW.push_back(vector<int> (0));
        groupB.push_back(vector<int> (0));
        int totalW = 0, totalB = 0;
        for(int j = 0; j < n; ++j){
            if(visited[j] == groupIdx){
                totalW += weight[j];
                totalB += beauty[j];
                groupW[groupIdx].push_back(weight[j]);
                groupB[groupIdx].push_back(beauty[j]);
            }
        }
        groupW[groupIdx].push_back(totalW);
        groupB[groupIdx].push_back(totalB);
        // cout << "group " << groupIdx << "\tweight: " << totalW << "\tBeauty: " << totalB << endl;
        ++groupIdx;
    }

    // knapsack
    // vector<int> table(W + 1, 0);
    // for(int w = W; w >= 0; --w){
    //     for(int i = 0; i < groupIdx; ++i){
    //         for(int k = 0; k < groupW[i].size(); ++k){
    //             if(w < groupW[i][k])    continue;
    //             table[w] = max(table[w], table[w - groupW[i][k]] + groupB[i][k]);
    //         }
    //     }
    // }
    // int ans = 0;
    // for(auto ele : table)   ans = max(ans, ele);
    // cout << ans << endl;

    int pre = 0, cur = 1;
    vector< vector<int> > table(2, vector<int> (W + 1, 0));
    for(int i = 0; i < groupIdx; ++i){
        table[cur].assign(W + 1, 0);
        for(int k = 0; k <= W; ++k){
            for(int j = 0; j < groupW[i].size(); ++j){
                if(k < groupW[i][j])   continue;
                table[cur][k] = max(table[cur][k],
                    max(table[pre][k], table[pre][k - groupW[i][j]] + groupB[i][j]));
            }
        }
        pre = 1 - pre, cur = 1 - cur;
    }
    int ans = 0;
    for(auto ele : table[pre])  ans = max(ele, ans);
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>
#define UNVISITED -1
#define POSINF 1 << 25
#define NEGINF -1 << 25
#define _ ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0), cout.precision(15);
using namespace std;

typedef long long int64;
typedef pair<int, int> ii;

vector<int> visited;
vector< vector<int> > AdjList, groupW, groupB;

void dfs(int u, int groupIdx){
    visited[u] = groupIdx;
    for(auto v : AdjList[u])
        if(visited[v] == UNVISITED)
            dfs(v, groupIdx);
}

int main(){ _
    int n, m, maxW;    cin >> n >> m >> maxW;
    visited.assign(n, UNVISITED);
    AdjList.assign(n, vector<int> (0));
    vector<int> weight(n, 0), beauty(n, 0);
    for(int i = 0; i < n; ++i)  cin >> weight[i];
    for(int i = 0; i < n; ++i)  cin >> beauty[i];
    for(int i = 0; i < m; ++i){
        int u, v;   cin >> u >> v;
        --u, --v;
        AdjList[u].push_back(v);
        AdjList[v].push_back(u);
    }

    int groupIdx = 0;
    for(int i = 0; i < n; ++i){
        if(visited[i] != UNVISITED)  continue;
        dfs(i, groupIdx);
        groupW.push_back(vector<int> (0));
        groupB.push_back(vector<int> (0));
        int totalW = 0, totalB = 0;
        for(int j = 0; j < n; ++j){
            if(visited[j] == groupIdx){
                totalW += weight[j];
                totalB += beauty[j];
                groupW[groupIdx].push_back(weight[j]);
                groupB[groupIdx].push_back(beauty[j]);
            }
        }
        groupW[groupIdx].push_back(totalW);
        groupB[groupIdx].push_back(totalB);
        // cout << "group " << groupIdx << "\tweight: " << totalW << "\tBeauty: " << totalB << endl;
        ++groupIdx;
    }

    // knapsack
    vector<int> table(maxW + 1, 0);
    for(int i = 0; i < groupIdx; ++i){
        for(int w = maxW; w >= 0; --w){
            for(int k = 0; k < groupW[i].size(); ++k){
                if(w < groupW[i][k])    continue;
                table[w] = max(table[w], table[w - groupW[i][k]] + groupB[i][k]);
            }
        }
    }
    int ans = 0;
    for(auto ele : table)   ans = max(ans, ele);
    cout << ans << endl;

    // int pre = 0, cur = 1;
    // vector< vector<int> > table(2, vector<int> (maxW + 1, 0));
    // for(int i = 0; i < groupIdx; ++i){
    //     table[cur].assign(maxW + 1, 0);
    //     for(int j = 0; j < groupW[i].size(); ++j){
    //         for(int k = 0; k <= maxW; ++k){
    //             if(k < groupW[i][j])   continue;
    //             table[cur][k] = max(table[cur][k],
    //                 max(table[pre][k], table[pre][k - groupW[i][j]] + groupB[i][j]));
    //         }
    //     }
    //     pre = 1 - pre, cur = 1 - cur;
    // }
    // int ans = 0;
    // for(auto ele : table[pre])  ans = max(ele, ans);
    // cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>
#define UNVISITED -1
#define POSINF 1 << 25
#define NEGINF -1 << 25
#define _ ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0), cout.precision(15);
using namespace std;

typedef long long int64;
typedef pair<int, int> ii;

vector<int> visited;
vector< vector<int> > AdjList, groupW, groupB;

void dfs(int u, int groupIdx){
    visited[u] = groupIdx;
    for(auto v : AdjList[u])
        if(visited[v] == UNVISITED)
            dfs(v, groupIdx);
}

int main(){ _
    int n, m, W;    cin >> n >> m >> W;
    visited.assign(n, UNVISITED);
    AdjList.assign(n, vector<int> (0));
    vector<int> weight(n, 0), beauty(n, 0);
    for(int i = 0; i < n; ++i)  cin >> weight[i];
    for(int i = 0; i < n; ++i)  cin >> beauty[i];
    for(int i = 0; i < m; ++i){
        int u, v;   cin >> u >> v;
        --u, --v;
        AdjList[u].push_back(v);
        AdjList[v].push_back(u);
    }

    int groupIdx = 0;
    for(int i = 0; i < n; ++i){
        if(visited[i] != UNVISITED)  continue;
        dfs(i, groupIdx);
        groupW.push_back(vector<int> (0));
        groupB.push_back(vector<int> (0));
        int totalW = 0, totalB = 0;
        for(int j = 0; j < n; ++j){
            if(visited[j] == groupIdx){
                totalW += weight[j];
                totalB += beauty[j];
                groupW[groupIdx].push_back(weight[j]);
                groupB[groupIdx].push_back(beauty[j]);
            }
        }
        groupW[groupIdx].push_back(totalW);
        groupB[groupIdx].push_back(totalB);
        // cout << "group " << groupIdx << "\tweight: " << totalW << "\tBeauty: " << totalB << endl;
        ++groupIdx;
    }

    // vector<int> table(W + 1, 0);
    // for(int i = 0; i < groupIdx; ++i){
    //     for(int w = W; w >= 0; --w){
    //         for(int k = 0; k < groupW[i].size(); ++k){
    //             if(w < groupW[i][k])    continue;
    //             table[w] = max(table[w], table[w - groupW[i][k]] + groupB[i][k]);
    //         }
    //     }
    // }
    // int ans = 0;
    // for(auto ele : table)   ans = max(ans, ele);
    // cout << ans << endl;

    int pre = 0, cur = 1;
    vector< vector<int> > table(2, vector<int> (W + 1, 0));
    for(int i = 0; i < groupIdx; ++i){
        table[cur].assign(W + 1, 0);
        for(int w = 0; w <= W; ++w){
            table[cur][w] = max(table[cur][w], table[pre][w]);
            for(int k = 0; k < groupW[i].size(); ++k){
                if(w < groupW[i][k])    continue;
                table[cur][w] = max(table[cur][w], table[pre][w - groupW[i][k]] + groupB[i][k]);
            }
        }
        pre = 1 - pre, cur = 1 - cur;
    }
    int ans = 0;
    for(auto ele : table[pre])  ans = max(ele, ans);
    cout << ans << endl;

    // int pre = 0, cur = 1;
    // vector< vector<int> > table(2, vector<int> (W + 1, 0));
    // for(int i = 0; i < groupIdx; ++i){
    //     table[cur].assign(W + 1, 0);
    //     for(int w = 0; w <= W; ++w){
    //         for(int j = 0; j < groupW[i].size(); ++j){
    //             if(w < groupW[i][j])   continue;
    //             table[cur][w] = max(table[cur][w],
    //                 max(table[pre][w], table[pre][w - groupW[i][j]] + groupB[i][j]));
    //         }
    //     }
    //     pre = 1 - pre, cur = 1 - cur;
    // }
    // int ans = 0;
    // for(auto ele : table[pre])  ans = max(ele, ans);
    // cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>
#define UNVISITED -1
#define POSINF 1 << 25
#define NEGINF -1 << 25
#define _ ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0), cout.precision(15);
using namespace std;

typedef long long int64;
typedef pair<int, int> ii;

vector<int> visited;
vector< vector<int> > AdjList, groupW, groupB;

void dfs(int u, int groupIdx){
    visited[u] = groupIdx;
    for(auto v : AdjList[u])
        if(visited[v] == UNVISITED)
            dfs(v, groupIdx);
}

int main(){ _
    int n, m, W;    cin >> n >> m >> W;
    visited.assign(n, UNVISITED);
    AdjList.assign(n, vector<int> (0));
    vector<int> weight(n, 0), beauty(n, 0);
    for(int i = 0; i < n; ++i)  cin >> weight[i];
    for(int i = 0; i < n; ++i)  cin >> beauty[i];
    for(int i = 0; i < m; ++i){
        int u, v;   cin >> u >> v;
        --u, --v;
        AdjList[u].push_back(v);
        AdjList[v].push_back(u);
    }

    int groupIdx = 0;
    for(int i = 0; i < n; ++i){
        if(visited[i] != UNVISITED)  continue;
        dfs(i, groupIdx);
        groupW.push_back(vector<int> (0));
        groupB.push_back(vector<int> (0));
        int totalW = 0, totalB = 0;
        for(int j = 0; j < n; ++j){
            if(visited[j] == groupIdx){
                totalW += weight[j];
                totalB += beauty[j];
                groupW[groupIdx].push_back(weight[j]);
                groupB[groupIdx].push_back(beauty[j]);
            }
        }
        groupW[groupIdx].push_back(totalW);
        groupB[groupIdx].push_back(totalB);
        // cout << "group " << groupIdx << "\tweight: " << totalW << "\tBeauty: " << totalB << endl;
        ++groupIdx;
    }

    // vector<int> table(W + 1, 0);
    // for(int i = 0; i < groupIdx; ++i){
    //     for(int w = W; w >= 0; --w){
    //         for(int k = 0; k < groupW[i].size(); ++k){
    //             if(w < groupW[i][k])    continue;
    //             table[w] = max(table[w], table[w - groupW[i][k]] + groupB[i][k]);
    //         }
    //     }
    // }
    // int ans = 0;
    // for(auto ele : table)   ans = max(ans, ele);
    // cout << ans << endl;

    // int pre = 0, cur = 1;
    // vector< vector<int> > table(2, vector<int> (W + 1, 0));
    // for(int i = 0; i < groupIdx; ++i){
    //     table[cur].assign(W + 1, 0);
    //     for(int w = 0; w <= W; ++w){
    //         table[cur][w] = max(table[cur][w], table[pre][w]);
    //         for(int k = 0; k < groupW[i].size(); ++k){
    //             if(w < groupW[i][k])    continue;
    //             table[cur][w] = max(table[cur][w], table[pre][w - groupW[i][k]] + groupB[i][k]);
    //         }
    //     }
    //     pre = 1 - pre, cur = 1 - cur;
    // }
    // int ans = 0;
    // for(auto ele : table[pre])  ans = max(ele, ans);
    // cout << ans << endl;

    int pre = 0, cur = 1;
    vector< vector<int> > table(2, vector<int> (W + 1, 0));
    for(int i = 0; i < groupIdx; ++i){
        table[cur].assign(W + 1, 0);
        for(int w = 0; w <= W; ++w){
            // table[cur][w] = max(table[cur][w], table[pre][w]);
            for(int j = 0; j < groupW[i].size(); ++j){
                if(w < groupW[i][j])   continue;
                table[cur][w] = max(table[cur][w], table[pre][w]);
                // table[cur][w] = max(table[cur][w],
                    // max(table[pre][w], table[pre][w - groupW[i][j]] + groupB[i][j]));
                table[cur][w] = max(table[cur][w], table[pre][w - groupW[i][j]] + groupB[i][j]);
            }
        }
        pre = 1 - pre, cur = 1 - cur;
    }
    int ans = 0;
    for(auto ele : table[pre])  ans = max(ele, ans);
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>
#define UNVISITED -1
#define POSINF 1 << 25
#define NEGINF -1 << 25
#define _ ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0), cout.precision(15);
using namespace std;

typedef long long int64;
typedef pair<int, int> ii;

vector<int> visited;
vector< vector<int> > AdjList, groupW, groupB;

void dfs(int u, int groupIdx){
    visited[u] = groupIdx;
    for(auto v : AdjList[u])
        if(visited[v] == UNVISITED)
            dfs(v, groupIdx);
}

int main(){ _
    int n, m, W;    cin >> n >> m >> W;
    visited.assign(n, UNVISITED);
    AdjList.assign(n, vector<int> (0));
    vector<int> weight(n, 0), beauty(n, 0);
    for(int i = 0; i < n; ++i)  cin >> weight[i];
    for(int i = 0; i < n; ++i)  cin >> beauty[i];
    for(int i = 0; i < m; ++i){
        int u, v;   cin >> u >> v;
        --u, --v;
        AdjList[u].push_back(v);
        AdjList[v].push_back(u);
    }

    int groupIdx = 0;
    for(int i = 0; i < n; ++i){
        if(visited[i] != UNVISITED)  continue;
        dfs(i, groupIdx);
        groupW.push_back(vector<int> (0));
        groupB.push_back(vector<int> (0));
        int totalW = 0, totalB = 0;
        for(int j = 0; j < n; ++j){
            if(visited[j] == groupIdx){
                totalW += weight[j];
                totalB += beauty[j];
                groupW[groupIdx].push_back(weight[j]);
                groupB[groupIdx].push_back(beauty[j]);
            }
        }
        groupW[groupIdx].push_back(totalW);
        groupB[groupIdx].push_back(totalB);
        // cout << "group " << groupIdx << "\tweight: " << totalW << "\tBeauty: " << totalB << endl;
        ++groupIdx;
    }

    // vector<int> table(W + 1, 0);
    // for(int i = 0; i < groupIdx; ++i){
    //     for(int w = W; w >= 0; --w){
    //         for(int k = 0; k < groupW[i].size(); ++k){
    //             if(w < groupW[i][k])    continue;
    //             table[w] = max(table[w], table[w - groupW[i][k]] + groupB[i][k]);
    //         }
    //     }
    // }
    // int ans = 0;
    // for(auto ele : table)   ans = max(ans, ele);
    // cout << ans << endl;

    // int pre = 0, cur = 1;
    // vector< vector<int> > table(2, vector<int> (W + 1, 0));
    // for(int i = 0; i < groupIdx; ++i){
    //     table[cur].assign(W + 1, 0);
    //     for(int w = 0; w <= W; ++w){
    //         table[cur][w] = max(table[cur][w], table[pre][w]);
    //         for(int k = 0; k < groupW[i].size(); ++k){
    //             if(w < groupW[i][k])    continue;
    //             table[cur][w] = max(table[cur][w], table[pre][w - groupW[i][k]] + groupB[i][k]);
    //         }
    //     }
    //     pre = 1 - pre, cur = 1 - cur;
    // }
    // int ans = 0;
    // for(auto ele : table[pre])  ans = max(ele, ans);
    // cout << ans << endl;

    int pre = 0, cur = 1;
    vector< vector<int> > table(2, vector<int> (W + 1, 0));
    for(int i = 0; i < groupIdx; ++i){
        table[cur].assign(W + 1, 0);
        for(int w = 0; w <= W; ++w){
            table[cur][w] = max(table[cur][w], table[pre][w]);
            for(int j = 0; j < groupW[i].size(); ++j){
                if(w < groupW[i][j])   continue;
                // table[cur][w] = max(table[cur][w], table[pre][w]);
                // table[cur][w] = max(table[cur][w],
                    // max(table[pre][w], table[pre][w - groupW[i][j]] + groupB[i][j]));
                table[cur][w] = max(table[cur][w], table[pre][w - groupW[i][j]] + groupB[i][j]);
            }
        }
        pre = 1 - pre, cur = 1 - cur;
    }
    int ans = 0;
    for(auto ele : table[pre])  ans = max(ele, ans);
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>
#define UNVISITED -1
#define POSINF 1 << 25
#define NEGINF -1 << 25
#define _ ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0), cout.precision(15);
using namespace std;

typedef long long int64;
typedef pair<int, int> ii;

vector<int> visited;
vector< vector<int> > AdjList, groupW, groupB;

void dfs(int u, int groupIdx){
    visited[u] = groupIdx;
    for(auto v : AdjList[u])
        if(visited[v] == UNVISITED)
            dfs(v, groupIdx);
}

int main(){ _
    int n, m, W;    cin >> n >> m >> W;
    visited.assign(n, UNVISITED);
    AdjList.assign(n, vector<int> (0));
    vector<int> weight(n, 0), beauty(n, 0);
    for(int i = 0; i < n; ++i)  cin >> weight[i];
    for(int i = 0; i < n; ++i)  cin >> beauty[i];
    for(int i = 0; i < m; ++i){
        int u, v;   cin >> u >> v;
        --u, --v;
        AdjList[u].push_back(v);
        AdjList[v].push_back(u);
    }

    int groupIdx = 0;
    for(int i = 0; i < n; ++i){
        if(visited[i] != UNVISITED)  continue;
        dfs(i, groupIdx);
        groupW.push_back(vector<int> (0));
        groupB.push_back(vector<int> (0));
        int totalW = 0, totalB = 0;
        for(int j = 0; j < n; ++j){
            if(visited[j] == groupIdx){
                totalW += weight[j];
                totalB += beauty[j];
                groupW[groupIdx].push_back(weight[j]);
                groupB[groupIdx].push_back(beauty[j]);
            }
        }
        groupW[groupIdx].push_back(totalW);
        groupB[groupIdx].push_back(totalB);
        // cout << "group " << groupIdx << "\tweight: " << totalW << "\tBeauty: " << totalB << endl;
        ++groupIdx;
    }

    vector<int> table(W + 1, 0);
    for(int i = 0; i < groupIdx; ++i){
        for(int w = W; w >= 0; --w){
            for(int k = 0; k < groupW[i].size(); ++k){
                if(w < groupW[i][k])    continue;
                table[w] = max(table[w], table[w - groupW[i][k]] + groupB[i][k]);
            }
        }
    }
    int ans = 0;
    for(auto ele : table)   ans = max(ans, ele);
    cout << ans << endl;

    // int pre = 0, cur = 1;
    // vector< vector<int> > table(2, vector<int> (W + 1, 0));
    // for(int i = 0; i < groupIdx; ++i){
    //     table[cur].assign(W + 1, 0);
    //     for(int w = 0; w <= W; ++w){
    //         for(int j = 0; j < groupW[i].size(); ++j){
    //             if(w < groupW[i][j])   continue;
    //             table[cur][w] = max(table[cur][w],
    //                 max(table[pre][w], table[pre][w - groupW[i][j]] + groupB[i][j]));
    //         }
    //     }
    //     pre = 1 - pre, cur = 1 - cur;
    // }
    // int ans = 0;
    // for(auto ele : table[pre])  ans = max(ele, ans);
    // cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>
#define UNVISITED -1
#define POSINF 1 << 25
#define NEGINF -1 << 25
#define _ ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0), cout.precision(15);
using namespace std;

typedef long long int64;
typedef pair<int, int> ii;

vector<int> visited;
vector< vector<int> > AdjList, groupW, groupB;

void dfs(int u, int groupIdx){
    visited[u] = groupIdx;
    for(auto v : AdjList[u])
        if(visited[v] == UNVISITED)
            dfs(v, groupIdx);
}

int main(){ _
    int n, m, W;    cin >> n >> m >> W;
    visited.assign(n, UNVISITED);
    AdjList.assign(n, vector<int> (0));
    vector<int> weight(n, 0), beauty(n, 0);
    for(int i = 0; i < n; ++i)  cin >> weight[i];
    for(int i = 0; i < n; ++i)  cin >> beauty[i];
    for(int i = 0; i < m; ++i){
        int u, v;   cin >> u >> v;
        --u, --v;
        AdjList[u].push_back(v);
        AdjList[v].push_back(u);
    }

    int groupIdx = 0;
    for(int i = 0; i < n; ++i){
        if(visited[i] != UNVISITED)  continue;
        dfs(i, groupIdx);
        groupW.push_back(vector<int> (0));
        groupB.push_back(vector<int> (0));
        int totalW = 0, totalB = 0;
        for(int j = 0; j < n; ++j){
            if(visited[j] == groupIdx){
                totalW += weight[j];
                totalB += beauty[j];
                groupW[groupIdx].push_back(weight[j]);
                groupB[groupIdx].push_back(beauty[j]);
            }
        }
        groupW[groupIdx].push_back(totalW);
        groupB[groupIdx].push_back(totalB);
        // cout << "group " << groupIdx << "\tweight: " << totalW << "\tBeauty: " << totalB << endl;
        ++groupIdx;
    }

    // vector<int> table(W + 1, 0);
    // for(int i = 0; i < groupIdx; ++i){
    //     for(int w = W; w >= 0; --w){
    //         for(int k = 0; k < groupW[i].size(); ++k){
    //             if(w < groupW[i][k])    continue;
    //             table[w] = max(table[w], table[w - groupW[i][k]] + groupB[i][k]);
    //         }
    //     }
    // }
    // int ans = 0;
    // for(auto ele : table)   ans = max(ans, ele);
    // cout << ans << endl;

    // int pre = 0, cur = 1;
    // vector< vector<int> > table(2, vector<int> (W + 1, 0));
    // for(int i = 0; i < groupIdx; ++i){
    //     table[cur].assign(W + 1, 0);
    //     for(int w = 0; w <= W; ++w){
    //         table[cur][w] = max(table[cur][w], table[pre][w]);
    //         for(int k = 0; k < groupW[i].size(); ++k){
    //             if(w < groupW[i][k])    continue;
    //             table[cur][w] = max(table[cur][w], table[pre][w - groupW[i][k]] + groupB[i][k]);
    //         }
    //     }
    //     pre = 1 - pre, cur = 1 - cur;
    // }
    // int ans = 0;
    // for(auto ele : table[pre])  ans = max(ele, ans);
    // cout << ans << endl;

    int pre = 0, cur = 1;
    vector< vector<int> > table(2, vector<int> (W + 1, 0));
    for(int i = 0; i < groupIdx; ++i){
        table[cur].assign(W + 1, 0);
        for(int w = 0; w <= W; ++w){
            table[cur][w] = max(table[cur][w], table[pre][w]);
            for(int j = 0; j < groupW[i].size(); ++j){
                if(w < groupW[i][j])   continue;
                // table[cur][w] = max(table[cur][w],
                    // max(table[pre][w], table[pre][w - groupW[i][j]] + groupB[i][j]));
                table[cur][w] = max(table[cur][w], table[pre][w - groupW[i][j]] + groupB[i][j]);
            }
        }
        pre = 1 - pre, cur = 1 - cur;
    }
    int ans = 0;
    for(auto ele : table[pre])  ans = max(ele, ans);
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>
#define UNVISITED -1
#define POSINF 1 << 25
#define NEGINF -1 << 25
#define _ ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0), cout.precision(15);
using namespace std;

typedef long long int64;
typedef pair<int, int> ii;

vector<int> visited;
vector< vector<int> > AdjList, groupW, groupB;

void dfs(int u, int groupIdx){
    visited[u] = groupIdx;
    for(auto v : AdjList[u])
        if(visited[v] == UNVISITED)
            dfs(v, groupIdx);
}

int main(){ _
    int n, m, W;    cin >> n >> m >> W;
    visited.assign(n, UNVISITED);
    AdjList.assign(n, vector<int> (0));
    vector<int> weight(n, 0), beauty(n, 0);
    for(int i = 0; i < n; ++i)  cin >> weight[i];
    for(int i = 0; i < n; ++i)  cin >> beauty[i];
    for(int i = 0; i < m; ++i){
        int u, v;   cin >> u >> v;
        --u, --v;
        AdjList[u].push_back(v);
        AdjList[v].push_back(u);
    }

    int groupIdx = 0;
    for(int i = 0; i < n; ++i){
        if(visited[i] != UNVISITED)  continue;
        dfs(i, groupIdx);
        groupW.push_back(vector<int> (0));
        groupB.push_back(vector<int> (0));
        int totalW = 0, totalB = 0;
        for(int j = 0; j < n; ++j){
            if(visited[j] == groupIdx){
                totalW += weight[j];
                totalB += beauty[j];
                groupW[groupIdx].push_back(weight[j]);
                groupB[groupIdx].push_back(beauty[j]);
            }
        }
        groupW[groupIdx].push_back(totalW);
        groupB[groupIdx].push_back(totalB);
        // cout << "group " << groupIdx << "\tweight: " << totalW << "\tBeauty: " << totalB << endl;
        ++groupIdx;
    }

    // vector<int> table(W + 1, 0);
    // for(int i = 0; i < groupIdx; ++i){
    //     for(int w = W; w >= 0; --w){
    //         for(int k = 0; k < groupW[i].size(); ++k){
    //             if(w < groupW[i][k])    continue;
    //             table[w] = max(table[w], table[w - groupW[i][k]] + groupB[i][k]);
    //         }
    //     }
    // }
    // int ans = 0;
    // for(auto ele : table)   ans = max(ans, ele);
    // cout << ans << endl;

    int pre = 0, cur = 1;
    vector< vector<int> > table(2, vector<int> (W + 1, 0));
    for(int i = 0; i < groupIdx; ++i){
        table[cur].assign(W + 1, 0);
        for(int w = W; w >= 0; --w){
            table[cur][w] = max(table[cur][w], table[pre][w]);
            for(int k = 0; k < groupW[i].size(); ++k){
                if(w < groupW[i][k])    continue;
                table[cur][w] = max(table[cur][w], table[pre][w - groupW[i][k]] + groupB[i][k]);
            }
        }
        pre = 1 - pre, cur = 1 - cur;
    }
    int ans = 0;
    for(auto ele : table[pre])  ans = max(ele, ans);
    cout << ans << endl;

    // int pre = 0, cur = 1;
    // vector< vector<int> > table(2, vector<int> (W + 1, 0));
    // for(int i = 0; i < groupIdx; ++i){
    //     table[cur].assign(W + 1, 0);
    //     for(int w = 0; w <= W; ++w){
    //         for(int j = 0; j < groupW[i].size(); ++j){
    //             if(w < groupW[i][j])   continue;
    //             table[cur][w] = max(table[cur][w],
    //                 max(table[pre][w], table[pre][w - groupW[i][j]] + groupB[i][j]));
    //         }
    //     }
    //     pre = 1 - pre, cur = 1 - cur;
    // }
    // int ans = 0;
    // for(auto ele : table[pre])  ans = max(ele, ans);
    // cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>
#define UNVISITED -1
#define POSINF 1 << 25
#define NEGINF -1 << 25
#define _ ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0), cout.precision(15);
using namespace std;

typedef long long int64;
typedef pair<int, int> ii;

vector<int> visited;
vector< vector<int> > AdjList, groupW, groupB;

void dfs(int u, int groupIdx){
    visited[u] = groupIdx;
    for(auto v : AdjList[u])
        if(visited[v] == UNVISITED)
            dfs(v, groupIdx);
}

int main(){ _
    int n, m, W;    cin >> n >> m >> W;
    visited.assign(n, UNVISITED);
    AdjList.assign(n, vector<int> (0));
    vector<int> weight(n, 0), beauty(n, 0);
    for(int i = 0; i < n; ++i)  cin >> weight[i];
    for(int i = 0; i < n; ++i)  cin >> beauty[i];
    for(int i = 0; i < m; ++i){
        int u, v;   cin >> u >> v;
        --u, --v;
        AdjList[u].push_back(v);
        AdjList[v].push_back(u);
    }

    int groupIdx = 0;
    for(int i = 0; i < n; ++i){
        if(visited[i] != UNVISITED)  continue;
        dfs(i, groupIdx);
        groupW.push_back(vector<int> (0));
        groupB.push_back(vector<int> (0));
        int totalW = 0, totalB = 0;
        for(int j = 0; j < n; ++j){
            if(visited[j] == groupIdx){
                totalW += weight[j];
                totalB += beauty[j];
                groupW[groupIdx].push_back(weight[j]);
                groupB[groupIdx].push_back(beauty[j]);
            }
        }
        groupW[groupIdx].push_back(totalW);
        groupB[groupIdx].push_back(totalB);
        // cout << "group " << groupIdx << "\tweight: " << totalW << "\tBeauty: " << totalB << endl;
        ++groupIdx;
    }

    // knapsack
    vector<int> table(W + 1, 0);
    for(int w = W; w >= 0; --w){
        for(int i = 0; i < groupIdx; ++i){
            for(int k = 0; k < groupW[i].size(); ++k){
                if(w < groupW[i][k])    continue;
                table[w] = max(table[w], table[w - groupW[i][k]] + groupB[i][k]);
            }
        }
    }
    int ans = 0;
    for(auto ele : table)   ans = max(ans, ele);
    cout << ans << endl;

    // int pre = 0, cur = 1;
    // vector< vector<int> > table(2, vector<int> (W + 1, 0));
    // for(int i = 0; i < groupIdx; ++i){
    //     table[cur].assign(W + 1, 0);
    //     for(int w = 0; w <= W; ++w){
    //         for(int j = 0; j < groupW[i].size(); ++j){
    //             if(w < groupW[i][j])   continue;
    //             table[cur][w] = max(table[cur][w],
    //                 max(table[pre][w], table[pre][w - groupW[i][j]] + groupB[i][j]));
    //         }
    //     }
    //     pre = 1 - pre, cur = 1 - cur;
    // }
    // int ans = 0;
    // for(auto ele : table[pre])  ans = max(ele, ans);
    // cout << ans << endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <string.h>
#include <map>
#include <set>
#include <algorithm>
#include <queue>

using namespace std;

#define mp(fst, snd) make_pair(fst, snd)
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef vector<int> vi;

int n, w[1001], b[1000], f[1000], dp[1000][1001], m, W;
vector<pii> friends[1000];
int Find(int x) {
	if (f[x] != x) f[x] = Find(f[x]);
	return f[x];
}
int solve(int p, int r) {
	int & res = dp[p][r];
	if (res != -1) {
		return res;
	}
	res = 0;
	if (p == n) {
		return res;
	}
	if (friends[p].size() == 0) {
		res = solve(p + 1, r);
	} else {
		res = solve(p + 1, r);
		int sumw = 0;
		int sumb = 0;
		for (auto pr : friends[p]) {
			if (pr.first <= r) {
				res = max(res, pr.second + solve(p + 1, r - pr.first));
			}
			sumw += pr.first;
			sumb += pr.second;
		}
		if (sumb && sumw <= r) {
			res = max(res, sumb + solve(p + 1, r - sumw));
		}
	}
	return res;
}

int main() {
	memset(dp, -1, sizeof dp);
	cin >> n >> m >> W;
	for (int i = 0; i < n; ++i) {
		cin >> w[i];
		f[i] = i;
	}
	for (int i = 0; i < n; ++i) {
		cin >> b[i];
	}
	for (int i = 0; i < m; ++i) {
		int u, v;
		cin >> u >> v;
		u--;
		v--;
		f[Find(u)] = Find(v);
	}
	for (int i = 0; i < n; ++i) {
		friends[Find(i)].push_back(make_pair(w[i], b[i]));
	}
	//for (int i = 0; i < n; ++i) {
		//if (friends[i].size()) {
			//cout << i << endl;
			//for (auto pr : friends[i]) {
				//cout << pr.first << " " << pr.second << endl;
			//}
		//}
	//}
	cout << solve(0, W) << endl;
	return 0;
}


#include <iostream>
#include <vector>
#include <string.h>
#include <map>
#include <set>
#include <algorithm>
#include <queue>

using namespace std;

#define mp(fst, snd) make_pair(fst, snd)
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef vector<int> vi;

int n, w[1001], b[1000], f[1000], dp[1000][1001], m, W;
vector<pii> friends[1000];
int Find(int x) {
	return f[x] == x ? x : (f[x] = Find(f[x]));
}
int solve(int p, int r) {
	int & res = dp[p][r];
	if (res != -1) {
		return res;
	}
	res = 0;
	if (p == n) {
		return res;
	}
	if (friends[p].size() == 0) {
		res = solve(p + 1, r);
	} else {
		res = solve(p + 1, r);
		int sumw = 0;
		int sumb = 0;
		for (auto pr : friends[p]) {
			if (pr.first <= r) {
				res = max(res, pr.second + solve(p + 1, r - pr.first));
			}
			sumw += pr.first;
			sumb += pr.second;
		}
		if (sumb && sumw <= r) {
			res = max(res, sumb + solve(p + 1, r - sumw));
		}
	}
	return res;
}

int main() {
	memset(dp, -1, sizeof dp);
	cin >> n >> m >> W;
	for (int i = 0; i < n; ++i) {
		cin >> w[i];
		f[i] = i;
	}
	for (int i = 0; i < n; ++i) {
		cin >> b[i];
	}
	for (int i = 0; i < m; ++i) {
		int u, v;
		cin >> u >> v;
		u--;
		v--;
		f[Find(u)] = Find(v);
	}
	for (int i = 0; i < n; ++i) {
		friends[Find(i)].push_back(make_pair(w[i], b[i]));
	}
	//for (int i = 0; i < n; ++i) {
		//if (friends[i].size()) {
			//cout << i << endl;
			//for (auto pr : friends[i]) {
				//cout << pr.first << " " << pr.second << endl;
			//}
		//}
	//}
	cout << solve(0, W) << endl;
	return 0;
}


#include <iostream>
#include <vector>
#include <string.h>
#include <map>
#include <set>
#include <algorithm>
#include <queue>

using namespace std;

#define mp(fst, snd) make_pair(fst, snd)
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef vector<int> vi;

int vis[1000];
vector<int> edges[1000];
int n, w[1001], b[1000], f[1000], dp[1001][1001], m, W;
vector<pii> friends[1000];
//int Find(int x) {
	//if (f[x] != x) f[x] = Find(f[x]);
	//return f[x];
//}
void dfs(int u, int p, int t) {
	vis[u] = 1;
	friends[t].push_back(make_pair(w[u], b[u]));
	for (int v : edges[u]) {
		if (!vis[v] && v != p) {
			dfs(v, u, t);
		}
	}
}
int solve(int p, int r) {
	int & res = dp[p][r];
	if (res != -1) {
		return res;
	}
	res = 0;
	if (p == n) {
		return 0;
	}
	if (friends[p].size() == 0) {
		res = solve(p + 1, r);
	} else {
		res = solve(p + 1, r);
		int sumw = 0;
		int sumb = 0;
		for (auto pr : friends[p]) {
			if (pr.first <= r) {
				res = max(res, pr.second + solve(p + 1, r - pr.first));
			}
			sumw += pr.first;
			sumb += pr.second;
		}
		if (sumb && sumw <= r) {
			res = max(res, sumb + solve(p + 1, r - sumw));
		}
	}
	return res;
}

int main() {
	memset(dp, -1, sizeof dp);
	cin >> n >> m >> W;
	for (int i = 0; i < n; ++i) {
		cin >> w[i];
		f[i] = i;
	}
	for (int i = 0; i < n; ++i) {
		cin >> b[i];
	}
	for (int i = 0; i < m; ++i) {
		int u, v;
		cin >> u >> v;
		u--;
		v--;
		edges[u].push_back(v);
		edges[v].push_back(u);
		//f[Find(v)] = Find(u);
	}
	for (int i = 0; i < n; ++i) {
		//friends[Find(i)].push_back(make_pair(w[i], b[i]));
		if (!vis[i]) {
			dfs(i, -1, i);
		}
	}
	//for (int i = 0; i < n; ++i) {
		//if (friends[i].size()) {
			//cout << i << endl;
			//for (auto pr : friends[i]) {
				//cout << pr.first << " " << pr.second << endl;
			//}
		//}
	//}
	cout << solve(0, W) << endl;
	return 0;
}


#include <iostream>
#include <vector>
#include <string.h>
#include <map>
#include <set>
#include <algorithm>
#include <queue>

using namespace std;

#define mp(fst, snd) make_pair(fst, snd)
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef vector<int> vi;

int vis[1000];
vector<int> edges[1000];
int n, w[1001], b[1000], f[1000], dp[1001][1001], m, W;
vector<pii> friends[1000];
//int Find(int x) {
	//if (f[x] != x) f[x] = Find(f[x]);
	//return f[x];
//}
void dfs(int u, int p, int t) {
	vis[u] = 1;
	friends[t].push_back(make_pair(w[u], b[u]));
	for (int v : edges[u]) {
		if (!vis[v] && v != p) {
			dfs(v, u, t);
		}
	}
}
int solve(int p, int r) {
	int & res = dp[p][r];
	if (res != -1) {
		return res;
	}
	res = 0;
	if (p == n) {
		return 0;
	}
	if (friends[p].size() == 0) {
		res = solve(p + 1, r);
	} else {
		res = solve(p + 1, r);
		int sumw = 0;
		int sumb = 0;
		for (auto pr : friends[p]) {
			if (pr.first <= r) {
				res = max(res, pr.second + solve(p + 1, r - pr.first));
			}
			sumw += pr.first;
			sumb += pr.second;
		}
		if (sumb && sumw <= r) {
			res = max(res, sumb + solve(p + 1, r - sumw));
		}
	}
	return res;
}

int main() {
	memset(dp, -1, sizeof dp);
	cin >> n >> m >> W;
	for (int i = 0; i < n; ++i) {
		f[i] = i;
		cin >> w[i];
	}
	for (int i = 0; i < n; ++i) {
		cin >> b[i];
	}
	for (int i = 0; i < m; ++i) {
		int u, v;
		cin >> u >> v;
		u--;
		v--;
		edges[u].push_back(v);
		edges[v].push_back(u);
		//f[Find(v)] = Find(u);
	}
	for (int i = 0; i < n; ++i) {
		//friends[Find(i)].push_back(make_pair(w[i], b[i]));
		if (!vis[i]) {
			dfs(i, -1, i);
		}
	}
	//for (int i = 0; i < n; ++i) {
		//if (friends[i].size()) {
			//cout << i << endl;
			//for (auto pr : friends[i]) {
				//cout << pr.first << " " << pr.second << endl;
			//}
		//}
	//}
	cout << solve(0, W) << endl;
	return 0;
}


#include <iostream>
#include <vector>
#include <string.h>
#include <map>
#include <set>
#include <algorithm>
#include <queue>

using namespace std;

#define mp(fst, snd) make_pair(fst, snd)
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef vector<int> vi;

int n, w[1001], b[1000], f[1000], dp[1000][1001], m, W;
vector<pii> friends[1000];
int Find(int x) {
	return f[x] == x ? x : (f[x] = Find(f[x]));
}
int solve(int p, int r) {
	int & res = dp[p][r];
	if (res != -1) {
		return res;
	}
	res = 0;
	if (p == n) {
		return res;
	}
	if (friends[p].size() == 0) {
		res = solve(p + 1, r);
	} else {
		res = solve(p + 1, r);
		int sumw = 0;
		int sumb = 0;
		for (auto pr : friends[p]) {
			if (pr.first <= r) {
				res = max(res, pr.second + solve(p + 1, r - pr.first));
			}
			sumw += pr.first;
			sumb += pr.second;
		}
		if (sumb && sumw <= r) {
			res = max(res, sumb + solve(p + 1, r - sumw));
		}
	}
	return res;
}

int main() {
	memset(dp, -1, sizeof dp);
	cin >> n >> m >> W;
	for (int i = 0; i < n; ++i) {
		cin >> w[i];
		f[i] = i;
	}
	for (int i = 0; i < n; ++i) {
		cin >> b[i];
	}
	for (int i = 0; i < m; ++i) {
		int u, v;
		cin >> u >> v;
		u--;
		v--;
		f[Find(v)] = Find(u);
	}
	for (int i = 0; i < n; ++i) {
		friends[Find(i)].push_back(make_pair(w[i], b[i]));
	}
	//for (int i = 0; i < n; ++i) {
		//if (friends[i].size()) {
			//cout << i << endl;
			//for (auto pr : friends[i]) {
				//cout << pr.first << " " << pr.second << endl;
			//}
		//}
	//}
	cout << solve(0, W) << endl;
	return 0;
}


#include <iostream>
#include <vector>
#include <string.h>
#include <map>
#include <set>
#include <algorithm>
#include <queue>

using namespace std;

#define mp(fst, snd) make_pair(fst, snd)
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef vector<int> vi;

int n, w[1001], b[1000], f[1000], dp[1000][1001], m, W;
vector<pii> friends[1000];
int Find(int x) {
	if (f[x] != x) f[x] = Find(f[x]);
	return f[x];
}
int solve(int p, int r) {
	int & res = dp[p][r];
	if (res != -1) {
		return res;
	}
	res = 0;
	if (p == n) {
		return res;
	}
	if (friends[p].size() == 0) {
		res = solve(p + 1, r);
	} else {
		res = solve(p + 1, r);
		int sumw = 0;
		int sumb = 0;
		for (auto pr : friends[p]) {
			if (pr.first <= r) {
				res = max(res, pr.second + solve(p + 1, r - pr.first));
			}
			sumw += pr.first;
			sumb += pr.second;
		}
		if (sumb && sumw <= r) {
			res = max(res, sumb + solve(p + 1, r - sumw));
		}
	}
	return res;
}

int main() {
	memset(dp, -1, sizeof dp);
	cin >> n >> m >> W;
	for (int i = 0; i < n; ++i) {
		cin >> w[i];
		f[i] = i;
	}
	for (int i = 0; i < n; ++i) {
		cin >> b[i];
	}
	for (int i = 0; i < m; ++i) {
		int u, v;
		cin >> u >> v;
		u--;
		v--;
		f[Find(v)] = Find(u);
	}
	for (int i = 0; i < n; ++i) {
		friends[Find(i)].push_back(make_pair(w[i], b[i]));
	}
	//for (int i = 0; i < n; ++i) {
		//if (friends[i].size()) {
			//cout << i << endl;
			//for (auto pr : friends[i]) {
				//cout << pr.first << " " << pr.second << endl;
			//}
		//}
	//}
	cout << solve(0, W) << endl;
	return 0;
}


#include <iostream>
#include <vector>
#include <string.h>
#include <map>
#include <set>
#include <algorithm>
#include <queue>

using namespace std;

#define mp(fst, snd) make_pair(fst, snd)
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef vector<int> vi;

int vis[1000];
vector<int> edges[1000];
int n, w[1001], b[1000], f[1000], dp[1000][1001], m, W;
vector<pii> friends[1000];
//int Find(int x) {
	//if (f[x] != x) f[x] = Find(f[x]);
	//return f[x];
//}
void dfs(int u, int p, int t) {
	vis[u] = 1;
	friends[t].push_back(make_pair(w[u], b[u]));
	for (int v : edges[u]) {
		if (!vis[v] && v != p) {
			dfs(v, u, t);
		}
	}
}
int solve(int p, int r) {
	int & res = dp[p][r];
	if (res != -1) {
		return res;
	}
	res = 0;
	if (p == n) {
		return 0;
	}
	if (friends[p].size() == 0) {
		res = solve(p + 1, r);
	} else {
		res = solve(p + 1, r);
		int sumw = 0;
		int sumb = 0;
		for (auto pr : friends[p]) {
			if (pr.first <= r) {
				res = max(res, pr.second + solve(p + 1, r - pr.first));
			}
			sumw += pr.first;
			sumb += pr.second;
		}
		if (sumb && sumw <= r) {
			res = max(res, sumb + solve(p + 1, r - sumw));
		}
	}
	return res;
}

int main() {
	memset(dp, -1, sizeof dp);
	cin >> n >> m >> W;
	for (int i = 0; i < n; ++i) {
		cin >> w[i];
		f[i] = i;
	}
	for (int i = 0; i < n; ++i) {
		cin >> b[i];
	}
	for (int i = 0; i < m; ++i) {
		int u, v;
		cin >> u >> v;
		u--;
		v--;
		edges[u].push_back(v);
		edges[v].push_back(u);
		//f[Find(v)] = Find(u);
	}
	for (int i = 0; i < n; ++i) {
		//friends[Find(i)].push_back(make_pair(w[i], b[i]));
		if (!vis[i]) {
			dfs(i, -1, i);
		}
	}
	//for (int i = 0; i < n; ++i) {
		//if (friends[i].size()) {
			//cout << i << endl;
			//for (auto pr : friends[i]) {
				//cout << pr.first << " " << pr.second << endl;
			//}
		//}
	//}
	cout << solve(0, W) << endl;
	return 0;
}


#include <iostream>
#include <vector>
#include <string.h>
#include <map>
#include <set>
#include <algorithm>
#include <queue>

using namespace std;

#define mp(fst, snd) make_pair(fst, snd)
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef vector<int> vi;

int n, w[1001], b[1000], f[1000], dp[1000][1001], m, W;
vector<pii> friends[1000];
int Find(int x) {
	return f[x] == x ? x : (f[x] = Find(f[x]));
}
int solve(int p, int r) {
	int & res = dp[p][r];
	if (res != -1) {
		return res;
	}
	res = 0;
	if (p == n) {
		return res;
	}
	if (friends[p].size() == 0) {
		res = solve(p + 1, r);
	} else {
		res = solve(p + 1, r);
		int sumw = 0;
		int sumb = 0;
		for (auto pr : friends[p]) {
			if (pr.first <= r) {
				res = max(res, pr.second + solve(p + 1, r - pr.first));
			}
			sumw += pr.first;
			sumb += pr.second;
		}
		if (sumb && sumw <= r) {
			res = max(res, sumb + solve(p + 1, r - sumw));
		}
	}
	return res;
}

int main() {
	memset(dp, -1, sizeof dp);
	cin >> n >> m >> W;
	for (int i = 0; i < n; ++i) {
		cin >> w[i];
		f[i] = i;
	}
	for (int i = 0; i < n; ++i) {
		cin >> b[i];
	}
	for (int i = 0; i < m; ++i) {
		int u, v;
		cin >> u >> v;
		u--;
		v--;
		f[v] = Find(u);
	}
	for (int i = 0; i < n; ++i) {
		friends[Find(i)].push_back(make_pair(w[i], b[i]));
	}
	cout << solve(0, W) << endl;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second

const int maxn = 1e3 + 100;
const int maxm = 1e5 + 100;
const int maxw = 1e3 + 100;

const int inf = 1e9;

vector<vector<int> > g(maxn);

vector<pair<int, int> > gl(maxn);

vector<vector<pair<int, int> > > col(maxn);

vector<bool> used(maxn);

void dfs(int v, int cur_color, int &allw, int &allb)
{
        used[v] = true;
        col[cur_color].push_back(gl[v]);
        allw += gl[v].x;
        allb += gl[v].y;
        for (int to : g[v])
        {
                if (!used[to])
                        dfs(to, cur_color, allw, allb);
        }
}

int main()
{
        int n, m, w;
        scanf("%d %d %d", &n, &m, &w);
        for (int i = 1; i <= n; ++i)
                scanf("%d", &gl[i].x);
        for (int i = 1; i <= n; ++i)
                scanf("%d", &gl[i].y);
        for (int i = 0; i < m; ++i)
        {
                int a, b;
                scanf("%d %d", &a, &b);
                g[a].push_back(b);
                g[b].push_back(a);
        }

        int cnt = 0;
        for (int i = 1; i <= n; ++i)
        {
                if (!used[i])
                {
                        int allw = 0, allb = 0;
                        dfs(i, cnt + 1, allw, allb);
                        col[cnt + 1].push_back({allw, allb});
                        cnt++;
                }
        }

        vector<vector<int> > d(maxn, vector<int> (maxw, -1));

        for (int i = 0; i < maxn; ++i)
                d[i][0] = 0;

        for (int i = 1; i <= cnt; ++i)
        {
                for (int curw = 0; curw <= w; ++curw)
                {
                        for (int j = 0; j < col[i].size(); ++j)
                        {
                                if (curw - col[i][j].x >= 0)
                                {
                                        if (d[i - 1][curw - col[i][j].x] != -1)
                                        {
                                                d[i][curw] = max(d[i][curw], d[i - 1][curw - col[i][j].x] + col[i][j].y);
                                        }
                                }
                        }
                }
        }
        int ans = 0;
        for (int i = 1; i <= cnt; ++i)
                for (int j = 0; j <= w; ++j)
                        ans = max(ans, d[i][j]);
        printf("%d", ans);
        return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second

const int maxn = 1e3 + 100;
const int maxm = 1e5 + 100;
const int maxw = 1e3 + 100;

const int inf = 1e9;

vector<vector<int> > g(maxn);

vector<pair<int, int> > gl(maxn);

vector<vector<pair<int, int> > > col(maxn);

vector<bool> used(maxn);

void dfs(int v, int cur_color, int &allw, int &allb)
{
        used[v] = true;
        col[cur_color].push_back(gl[v]);
        allw += gl[v].x;
        allb += gl[v].y;
        for (int to : g[v])
        {
                if (!used[to])
                        dfs(to, cur_color, allw, allb);
        }
}

int main()
{
        int n, m, w;
        scanf("%d %d %d", &n, &m, &w);
        for (int i = 1; i <= n; ++i)
                scanf("%d", &gl[i].x);
        for (int i = 1; i <= n; ++i)
                scanf("%d", &gl[i].y);
        for (int i = 0; i < m; ++i)
        {
                int a, b;
                scanf("%d %d", &a, &b);
                g[a].push_back(b);
                g[b].push_back(a);
        }

        int cnt = 0;
        for (int i = 1; i <= n; ++i)
        {
                if (!used[i])
                {
                        int allw = 0, allb = 0;
                        dfs(i, cnt + 1, allw, allb);
                        col[cnt + 1].push_back({allw, allb});
                        cnt++;
                }
        }

        vector<vector<int> > d(maxn, vector<int> (maxw, -1));

        for (int i = 0; i < maxn; ++i)
                d[i][0] = 0;

        for (int i = 1; i <= cnt; ++i)
        {
                for (int curw = 0; curw <= w; ++curw)
                {
                        if (d[i - 1][curw] != -1)
                                d[i][curw] = d[i - 1][curw];
                        for (int j = 0; j < col[i].size(); ++j)
                        {
                                if (curw - col[i][j].x >= 0)
                                {
                                        if (d[i - 1][curw - col[i][j].x] != -1)
                                        {
                                                d[i][curw] = max(d[i][curw], d[i - 1][curw - col[i][j].x] + col[i][j].y);
                                        }
                                }
                        }
                }
        }
        int ans = 0;
        for (int i = 1; i <= cnt; ++i)
                for (int j = 0; j <= w; ++j)
                        ans = max(ans, d[i][j]);
        printf("%d", ans);
        return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second

const int maxn = 1e3 + 100;
const int maxm = 1e5 + 100;
const int maxw = 1e3 + 100;

const int inf = 1e9;

vector<vector<int> > g(maxn);

vector<pair<int, int> > gl(maxn);

vector<vector<pair<int, int> > > col(maxn);

vector<bool> used(maxn);

void dfs(int v, int cur_color, int &allw, int &allb)
{
        used[v] = true;
        col[cur_color].push_back(gl[v]);
        allw += gl[v].x;
        allb += gl[v].y;
        for (int to : g[v])
        {
                if (!used[to])
                        dfs(to, cur_color, allw, allb);
        }
}

int main()
{
        int n, m, w;
        scanf("%d %d %d", &n, &m, &w);
        for (int i = 1; i <= n; ++i)
                scanf("%d", &gl[i].x);
        for (int i = 1; i <= n; ++i)
                scanf("%d", &gl[i].y);
        for (int i = 0; i < m; ++i)
        {
                int a, b;
                scanf("%d %d", &a, &b);
                g[a].push_back(b);
                g[b].push_back(a);
        }

        int cnt = 0;
        for (int i = 1; i <= n; ++i)
        {
                if (!used[i])
                {
                        int allw = 0, allb = 0;
                        dfs(i, cnt + 1, allw, allb);
                        col[cnt + 1].push_back({allw, allb});
                        cnt++;
                }
        }

        vector<vector<int> > d(maxn, vector<int> (maxw, -1));

        for (int i = 0; i < maxn; ++i)
                d[i][0] = 0;

        for (int i = 1; i <= cnt; ++i)
        {
                for (int curw = 0; curw <= w; ++curw)
                {
                        if (d[i - 1][curw] != -1)
                                d[i][curw] = d[i - 1][curw];
                        for (int j = 0; j < col[i].size(); ++j)
                        {
                                if (curw - col[i][j].x >= 0)
                                {
                                        if (d[i - 1][curw - col[i][j].x] != -1)
                                        {
                                                d[i][curw] = max(d[i][curw], d[i - 1][curw - col[i][j].x] + col[i][j].y);
                                        }
                                }
                        }
                }
        }
        int ans = 0;
        for (int j = 0; j <= w; ++j)
                ans = max(ans, d[cnt][j]);
        printf("%d", ans);
        return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second

const int maxn = 1e3 + 100;
const int maxm = 1e5 + 100;
const int maxw = 1e3 + 100;

const int inf = 1e9;

vector<vector<int> > g(maxn);

vector<pair<int, int> > gl(maxn);

vector<vector<pair<int, int> > > col(maxn);

vector<bool> used(maxn);

void dfs(int v, int cur_color, int &allw, int &allb)
{
        used[v] = true;
        col[cur_color].push_back(gl[v]);
        allw += gl[v].x;
        allb += gl[v].y;
        for (int to : g[v])
        {
                if (!used[to])
                        dfs(to, cur_color, allw, allb);
        }
}

int main()
{
        int n, m, w;
        scanf("%d %d %d", &n, &m, &w);
        for (int i = 1; i <= n; ++i)
                scanf("%d", &gl[i].x);
        for (int i = 1; i <= n; ++i)
                scanf("%d", &gl[i].y);
        for (int i = 0; i < m; ++i)
        {
                int a, b;
                scanf("%d %d", &a, &b);
                g[a].push_back(b);
                g[b].push_back(a);
        }

        int cnt = 0;
        for (int i = 1; i <= n; ++i)
        {
                if (!used[i])
                {
                        int allw = 0, allb = 0;
                        dfs(i, cnt + 1, allw, allb);
                        col[cnt + 1].push_back({allw, allb});
                        cnt++;
                }
        }

        vector<vector<int> > d(maxn, vector<int> (maxw, 0));

        for (int i = 1; i <= cnt; ++i)
        {
                for (int curw = 0; curw <= w; ++curw)
                {
                        if (d[i - 1][curw] != -1)
                                d[i][curw] = d[i - 1][curw];
                        for (int j = 0; j < col[i].size(); ++j)
                        {
                                if (curw - col[i][j].x >= 0)
                                {
                                        d[i][curw] = max(d[i][curw], d[i - 1][curw - col[i][j].x] + col[i][j].y);
                                }
                        }
                }
        }
        int ans = 0;
        for (int j = 0; j <= w; ++j)
                ans = max(ans, d[cnt][j]);
        printf("%d", ans);
        return 0;
}


#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
#include <vector>
using namespace std;
const int MAXN=11100;
int n,m,W;
long long w[MAXN];
long long b[MAXN];
vector <int> G[MAXN];
int par[MAXN];//父亲
int r[MAXN];//树的高度
//初始化n个元素
void init(int n)
{
    for(int i=0;i<=n;i++)
    {
        par[i]=i;
        r[i]=0;
    }
}
//查询数的根
int find(int x)
{
    if(par[x]==x)
        return x;
    else
        return par[x]=find(par[x]);
}
//合并x和y所属的集合
void unite(int x,int y){
    x=find(x);
    y=find(y);
    if(x==y)
        return;
    if(r[x]<r[y])
        par[x]=y;
    else
        par[y]=x;
    if(r[x]==r[y])
        r[x]++;
}

bool same(int x,int y)
{
    return find(x)==find(y);
}

long long f[MAXN];
int a[MAXN];
int main()
{
    memset(f,0,sizeof(f));
    scanf("%d%d%d",&n,&m,&W);
    for(int i=1;i<=n;i++)
        scanf("%I64d",w+i);
    for(int i=1;i<=n;i++)
        scanf("%I64d",b+i);
    int num=0;
    init(n);
    for(int i=0;i<m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        unite(x,y);
    }
    memset(a,-1,sizeof(a));
    for(int i=1;i<=n;i++){
        if(a[find(i)]==-1){
            a[find(i)]=num++;
        }
        G[a[find(i)]].push_back(i);
    }
    for(int i=0;i<num;i++){
        long long x=0,y=0;
        if(G[i].size()>1){
        for(int j=0;j<G[i].size();j++){
            x+=w[G[i][j]];
            y+=b[G[i][j]];
        }
        n++;
        w[n]=x;
        b[n]=y;
        G[i].push_back(n);
        }
    }
    for(int k=0;k<num;k++){
        for(int v=W;v>=0;v--){
            for(int i=0;i<G[k].size();i++){
                int temp=G[k][i];
                if(v>=w[temp])
                    f[v]=max(f[v],f[v-w[temp]]+b[temp]);
            }
        }
    }
    long long MAX=0;
    for(int i=0;i<=W;i++){
        MAX=max(MAX,f[i]);
    }
    printf("%I64d\n",MAX);
}


#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
#include <vector>
using namespace std;
const int MAXN=2100;
int n,m,W;
int w[MAXN];
int b[MAXN];
vector <int> G[MAXN];
int par[MAXN];//父亲
int r[MAXN];//树的高度
//初始化n个元素
void init(int n)
{
    for(int i=0;i<=n;i++)
    {
        par[i]=i;
        r[i]=0;
    }
}
//查询数的根
int find(int x)
{
    if(par[x]==x)
        return x;
    else
        return par[x]=find(par[x]);
}
//合并x和y所属的集合
void unite(int x,int y){
    x=find(x);
    y=find(y);
    if(x==y)
        return;
    if(r[x]<r[y])
        par[x]=y;
    else
        par[y]=x;
    if(r[x]==r[y])
        r[x]++;
}

bool same(int x,int y)
{
    return find(x)==find(y);
}

int f[MAXN];
int a[MAXN];
int main()
{
    memset(f,0,sizeof(f));
    scanf("%d%d%d",&n,&m,&W);
    for(int i=1;i<=n;i++)
        scanf("%d",w+i);
    for(int i=1;i<=n;i++)
        scanf("%d",b+i);
    int num=0;
    init(n);
    for(int i=0;i<m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        unite(x,y);
    }
    for(int i=1;i<=n;i++){
        if(find(i)==i){
            a[i]=num++;
            G[a[i]].push_back(i);
        }
        else{
            G[a[find(i)]].push_back(i);
        }
    }
    for(int i=0;i<num;i++){
        int x=0,y=0;
        if(G[i].size()>1){
        for(int j=0;j<G[i].size();j++){
            x+=w[G[i][j]];
            y+=b[G[i][j]];
        }
        n++;
        w[n]=x;
        b[n]=y;
        G[i].push_back(n);
        }
    }
    for(int k=0;k<num;k++){
        for(int v=W;v>=0;v--){
            for(int i=0;i<G[k].size();i++){
                int temp=G[k][i];
                if(v>=w[temp])
                    f[v]=max(f[v],f[v-w[temp]]+b[temp]);
            }
        }
    }
    printf("%d\n",f[W]);
}


#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
#include <vector>
using namespace std;
const int MAXN=11100;
int n,m,W;
long long w[MAXN];
long long b[MAXN];
vector <int> G[MAXN];
int par[MAXN];//父亲
int r[MAXN];//树的高度
//初始化n个元素
void init(int n)
{
    for(int i=0;i<=n;i++)
    {
        par[i]=i;
        r[i]=0;
    }
}
//查询数的根
int find(int x)
{
    if(par[x]==x)
        return x;
    else
        return par[x]=find(par[x]);
}
//合并x和y所属的集合
void unite(int x,int y){
    x=find(x);
    y=find(y);
    if(x==y)
        return;
    if(r[x]<r[y])
        par[x]=y;
    else
        par[y]=x;
    if(r[x]==r[y])
        r[x]++;
}

bool same(int x,int y)
{
    return find(x)==find(y);
}

long long f[MAXN];
int a[MAXN];
int main()
{
    memset(f,0,sizeof(f));
    scanf("%d%d%d",&n,&m,&W);
    for(int i=1;i<=n;i++)
        scanf("%I64d",w+i);
    for(int i=1;i<=n;i++)
        scanf("%I64d",b+i);
    int num=0;
    init(n);
    for(int i=0;i<m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        unite(x,y);
    }
    for(int i=1;i<=n;i++){
        if(find(i)==i){
            a[i]=num++;
            G[a[i]].push_back(i);
        }
        else{
            G[a[find(i)]].push_back(i);
        }
    }
    for(int i=0;i<num;i++){
        long long x=0,y=0;
        if(G[i].size()>1){
        for(int j=0;j<G[i].size();j++){
            x+=w[G[i][j]];
            y+=b[G[i][j]];
        }
        n++;
        w[n]=x;
        b[n]=y;
        G[i].push_back(n);
        }
    }
    for(int k=0;k<num;k++){
        for(int v=W;v>=0;v--){
            for(int i=0;i<G[k].size();i++){
                int temp=G[k][i];
                if(v>=w[temp])
                    f[v]=max(f[v],f[v-w[temp]]+b[temp]);
            }
        }
    }
    long long MAX=0;
    for(int i=0;i<=W;i++){
        MAX=max(MAX,f[i]);
    }
    printf("%I64d\n",MAX);
}


#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
#include <vector>
using namespace std;
const int MAXN=4100;
int n,m,W;
int w[MAXN];
int b[MAXN];
vector <int> G[MAXN];
int par[MAXN];//父亲
int r[MAXN];//树的高度
//初始化n个元素
void init(int n)
{
    for(int i=0;i<=n;i++)
    {
        par[i]=i;
        r[i]=0;
    }
}
//查询数的根
int find(int x)
{
    if(par[x]==x)
        return x;
    else
        return par[x]=find(par[x]);
}
//合并x和y所属的集合
void unite(int x,int y){
    x=find(x);
    y=find(y);
    if(x==y)
        return;
    if(r[x]<r[y])
        par[x]=y;
    else
        par[y]=x;
    if(r[x]==r[y])
        r[x]++;
}

bool same(int x,int y)
{
    return find(x)==find(y);
}

int f[MAXN];
int a[MAXN];
int main()
{
    memset(f,0,sizeof(f));
    scanf("%d%d%d",&n,&m,&W);
    for(int i=1;i<=n;i++)
        scanf("%d",w+i);
    for(int i=1;i<=n;i++)
        scanf("%d",b+i);
    int num=0;
    init(n);
    for(int i=0;i<m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        unite(x,y);
    }
    for(int i=1;i<=n;i++){
        if(find(i)==i){
            a[i]=num++;
            G[a[i]].push_back(i);
        }
        else{
            G[a[find(i)]].push_back(i);
        }
    }
    for(int i=0;i<num;i++){
        int x=0,y=0;
        if(G[i].size()>1){
        for(int j=0;j<G[i].size();j++){
            x+=w[G[i][j]];
            y+=b[G[i][j]];
        }
        n++;
        w[n]=x;
        b[n]=y;
        G[i].push_back(n);
        }
    }
    for(int k=0;k<num;k++){
        for(int v=W;v>=0;v--){
            for(int i=0;i<G[k].size();i++){
                int temp=G[k][i];
                if(v>=w[temp])
                    f[v]=max(f[v],f[v-w[temp]]+b[temp]);
            }
        }
    }
    int MAX=0;
    for(int i=0;i<=W;i++){
        MAX=max(MAX,f[i]);
    }
    printf("%d\n",MAX);
}


#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
#include <vector>
using namespace std;
const int MAXN=4100;
int n,m,W;
long long w[MAXN];
long long b[MAXN];
vector <int> G[MAXN];
int par[MAXN];//父亲
int r[MAXN];//树的高度
//初始化n个元素
void init(int n)
{
    for(int i=0;i<=n;i++)
    {
        par[i]=i;
        r[i]=0;
    }
}
//查询数的根
int find(int x)
{
    if(par[x]==x)
        return x;
    else
        return par[x]=find(par[x]);
}
//合并x和y所属的集合
void unite(int x,int y){
    x=find(x);
    y=find(y);
    if(x==y)
        return;
    if(r[x]<r[y])
        par[x]=y;
    else
        par[y]=x;
    if(r[x]==r[y])
        r[x]++;
}

bool same(int x,int y)
{
    return find(x)==find(y);
}

long long f[MAXN];
int a[MAXN];
int main()
{
    memset(f,0,sizeof(f));
    scanf("%d%d%d",&n,&m,&W);
    for(int i=1;i<=n;i++)
        scanf("%I64d",w+i);
    for(int i=1;i<=n;i++)
        scanf("%I64d",b+i);
    int num=0;
    init(n);
    for(int i=0;i<m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        unite(x,y);
    }
    for(int i=1;i<=n;i++){
        if(find(i)==i){
            a[i]=num++;
            G[a[i]].push_back(i);
        }
        else{
            G[a[find(i)]].push_back(i);
        }
    }
    for(int i=0;i<num;i++){
        long long x=0,y=0;
        if(G[i].size()>1){
        for(int j=0;j<G[i].size();j++){
            x+=w[G[i][j]];
            y+=b[G[i][j]];
        }
        n++;
        w[n]=x;
        b[n]=y;
        G[i].push_back(n);
        }
    }
    for(int k=0;k<num;k++){
        for(int v=W;v>=0;v--){
            for(int i=0;i<G[k].size();i++){
                int temp=G[k][i];
                if(v>=w[temp])
                    f[v]=max(f[v],f[v-w[temp]]+b[temp]);
            }
        }
    }
    long long MAX=0;
    for(int i=0;i<=W;i++){
        MAX=max(MAX,f[i]);
    }
    printf("%I64d\n",MAX);
}


#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
#include <vector>
using namespace std;
const int MAXN=2100;
int n,m,W;
int w[MAXN];
int b[MAXN];
vector <int> G[MAXN];
int par[MAXN];//父亲
int r[MAXN];//树的高度
//初始化n个元素
void init(int n)
{
    for(int i=0;i<=n;i++)
    {
        par[i]=i;
        r[i]=0;
    }
}
//查询数的根
int find(int x)
{
    if(par[x]==x)
        return x;
    else
        return par[x]=find(par[x]);
}
//合并x和y所属的集合
void unite(int x,int y){
    x=find(x);
    y=find(y);
    if(x==y)
        return;
    if(r[x]<r[y])
        par[x]=y;
    else
        par[y]=x;
    if(r[x]==r[y])
        r[x]++;
}

bool same(int x,int y)
{
    return find(x)==find(y);
}

int f[MAXN];
int a[MAXN];
int main()
{
    scanf("%d%d%d",&n,&m,&W);
    for(int i=0;i<n;i++)
        scanf("%d",w+i);
    for(int i=0;i<n;i++)
        scanf("%d",b+i);
    int num=0;
    init(n);
    for(int i=0;i<m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        unite(x,y);
    }
    for(int i=1;i<=n;i++){
        if(find(i)==i){
            a[i]=num++;
            G[a[i]].push_back(i);
        }
        else{
            G[a[find(i)]].push_back(i);
        }
    }
    for(int i=0;i<num;i++){
        int x=0,y=0;
        for(int j=0;j<G[i].size();j++){
            x+=w[G[i][j]];
            y+=b[G[i][j]];
        }
        w[n]=x;
        b[n]=y;
        G[i].push_back(n);
        n++;
    }
    for(int k=0;k<num;k++){
        for(int v=W;v>=0;v--){
            for(int i=0;i<G[k].size();i++){
                int temp=G[k][i];
                f[v]=max(f[v],f[v-w[temp]]+b[temp]);
            }
        }
    }
    printf("%d\n",f[W]);
}


//The best is yet to come...
 #include <iostream>
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define inf 1000000000000
#define mod 1000000007
#define pb push_back
#define mp make_pair
#define all(v) v.begin(),v.end()
#define S second
#define F first
#define boost1 ios::sync_with_stdio(false);
#define boost2 cin.tie(0);
#define mem(a,val) memset(a,val,sizeof a)
#define endl "\n"
#define maxn 100001

ll par[maxn],sumw[maxn],sumb[maxn],w[maxn],b[maxn],dp[2001][2001];
ll assign[maxn];
vector<ll>store[maxn];

ll find(ll x)
{
	if(par[x]==x)
	return x;
	return par[x]=find(par[x]);
}
int main()
{
	boost1;boost2;
	ll i,j,n,m,limit,x,y,xp,yp,ctr=0,k;
	cin>>n>>m>>limit;
	for(i=1;i<=n;i++)
	cin>>w[i];
	for(i=1;i<=n;i++)
	cin>>b[i];
	for(i=1;i<=n;i++)
	par[i]=i;
	for(i=1;i<=m;i++)
	{
		cin>>x>>y;
		xp=find(x);
		yp=find(y);
		if(xp==yp)
		continue;
		par[xp]=yp;
	}
	for(i=1;i<=n;i++)
	{
		if(find(i)==i)
		{
			ctr++;
			assign[i]=ctr;
		}
	}
	for(i=1;i<=n;i++)
	{
		x=find(i);
		x=assign[x];
		store[x].pb(i);
		sumb[x]+=b[i];
		sumw[x]+=w[i];
	}
	assert(ctr<=n);
	for(i=1;i<=ctr;i++)
	{
		for(j=0;j<=limit;j++)
		{
			dp[i][j]=max(dp[i][j],dp[i-1][j]);
			dp[i][j]=max(dp[i][j],dp[i][j-1]);
			if(j>=sumw[i])
			dp[i][j]=max(dp[i][j],dp[i-1][j-sumw[i]]+sumb[i]);
			for(k=0;k<store[i].size();k++)
			{
				x=store[i][k];
				if(j-w[x]>=0)
				dp[i][j]=max(dp[i][j],dp[i-1][j-w[x]]+b[x]);
			}
		}
	}
	ll ans=0;
	for(i=0;i<=limit;i++)
	ans=max(ans,dp[ctr][i]);
	assert(ans==dp[ctr][limit]);
	cout<<dp[ctr][limit];
	return 0;
}


//The best is yet to come...
 #include <iostream>
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define inf 1000000000000
#define mod 1000000007
#define pb push_back
#define mp make_pair
#define all(v) v.begin(),v.end()
#define S second
#define F first
#define boost1 ios::sync_with_stdio(false);
#define boost2 cin.tie(0);
#define mem(a,val) memset(a,val,sizeof a)
#define endl "\n"
#define maxn 100001

ll par[maxn],sumw[maxn],sumb[maxn],w[maxn],b[maxn],dp[1001][1001];
ll assign[maxn];
vector<ll>store[maxn];

ll find(ll x)
{
	if(par[x]==x)
	return x;
	return par[x]=find(par[x]);
}
int main()
{
	boost1;boost2;
	ll i,j,n,m,limit,x,y,xp,yp,ctr=0,k;
	cin>>n>>m>>limit;
	for(i=1;i<=n;i++)
	cin>>w[i];
	for(i=1;i<=n;i++)
	cin>>b[i];
	for(i=1;i<=n;i++)
	{
		par[i]=i;
		sumw[i]=w[i];
		sumb[i]=b[i];
	}
	for(i=1;i<=m;i++)
	{
		cin>>x>>y;
		xp=find(x);
		yp=find(y);
		if(xp==yp)
		continue;
		par[xp]=yp;
		sumw[yp]+=sumw[xp];
		sumb[yp]+=sumb[xp];
	}

	for(i=1;i<=n;i++)
	{
		if(find(i)==i)
		{
			ctr++;
			assign[i]=ctr;
		}
	}
	mem(sumw,0);
	mem(sumb,0);
	for(i=1;i<=n;i++)
	{
		x=find(i);
		x=assign[x];
		store[x].pb(i);
		sumb[x]+=b[i];
		sumw[x]+=w[i];
	}
	for(i=1;i<=ctr;i++)
	{
		for(j=0;j<=limit;j++)
		{
			dp[i][j]=max(dp[i][j],dp[i-1][j]);
			dp[i][j]=max(dp[i][j],dp[i][j-1]);
			if(j>=sumw[i])
			dp[i][j]=max(dp[i][j],dp[i-1][j-sumw[i]]+sumb[i]);
			for(k=0;k<store[i].size();k++)
			{
				x=store[i][k];
				if(j-w[x]>=0)
				dp[i][j]=max(dp[i][j],dp[i-1][j-w[x]]+b[x]);
			}
		}
	}
	ll ans=0;
	for(i=0;i<=limit;i++)
	ans=max(ans,dp[ctr][i]);
	assert(ans==dp[ctr][limit]);
	cout<<dp[ctr][limit];
	return 0;
}


//The best is yet to come...
 #include <iostream>
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define inf 1000000000000
#define mod 1000000007
#define pb push_back
#define mp make_pair
#define all(v) v.begin(),v.end()
#define S second
#define F first
#define boost1 ios::sync_with_stdio(false);
#define boost2 cin.tie(0);
#define mem(a,val) memset(a,val,sizeof a)
#define endl "\n"
#define maxn 100001

ll par[maxn],sumw[maxn],sumb[maxn],w[maxn],b[maxn],dp[1001][1001];
ll assign[maxn];
vector<ll>store[maxn];

ll find(ll x)
{
	if(par[x]==x)
	return x;
	return par[x]=find(par[x]);
}
int main()
{
	boost1;boost2;
	ll i,j,n,m,limit,x,y,xp,yp,ctr=0,k;
	cin>>n>>m>>limit;
	for(i=1;i<=n;i++)
	cin>>w[i];
	for(i=1;i<=n;i++)
	cin>>b[i];
	for(i=1;i<=n;i++)
	{
		par[i]=i;
		sumw[i]=w[i];
		sumb[i]=b[i];
	}
	for(i=1;i<=m;i++)
	{
		cin>>x>>y;
		xp=find(x);
		yp=find(y);
		if(xp==yp)
		continue;
		par[xp]=yp;
		sumw[yp]+=sumw[xp];
		sumb[yp]+=sumb[xp];
	}

	for(i=1;i<=n;i++)
	{
		if(find(i)==i)
		{
			ctr++;
			assign[i]=ctr;
		}
	}
	mem(sumw,0);
	mem(sumb,0);
	for(i=1;i<=n;i++)
	{
		x=find(i);
		x=assign[x];
		store[x].pb(i);
		sumb[x]+=b[i];
		sumw[x]+=w[i];
	}
	for(i=1;i<=ctr;i++)
	{
		for(j=0;j<=limit;j++)
		{
			dp[i][j]=max(dp[i][j],dp[i-1][j]);
			dp[i][j]=max(dp[i][j],dp[i][j-1]);
			if(j>=sumw[i])
			dp[i][j]=max(dp[i][j],dp[i-1][j-sumw[i]]+sumb[i]);
			for(k=0;k<store[i].size();k++)
			{
				x=store[i][k];
				if(j-w[x]>=0)
				dp[i][j]=max(dp[i][j],dp[i-1][j-w[x]]+b[x]);
			}
		}
	}
	cout<<dp[ctr][limit];
	return 0;
}


//The best is yet to come...
 #include <iostream>
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define inf 1000000000000
#define mod 1000000007
#define pb push_back
#define mp make_pair
#define all(v) v.begin(),v.end()
#define S second
#define F first
#define boost1 ios::sync_with_stdio(false);
#define boost2 cin.tie(0);
#define mem(a,val) memset(a,val,sizeof a)
#define endl "\n"
#define maxn 100001

ll par[maxn],sumw[maxn],sumb[maxn],w[maxn],b[maxn],dp[1001][1001];
ll assign[maxn];
vector<ll>store[maxn];

ll find(ll x)
{
	if(par[x]==x)
	return x;
	return par[x]=find(par[x]);
}
int main()
{
	boost1;boost2;
	ll i,j,n,m,limit,x,y,xp,yp,ctr=0,k;
	cin>>n>>m>>limit;
	for(i=1;i<=n;i++)
	cin>>w[i];
	for(i=1;i<=n;i++)
	cin>>b[i];
	for(i=1;i<=n;i++)
	{
		par[i]=i;
		sumw[i]=w[i];
		sumb[i]=b[i];
	}
	for(i=1;i<=m;i++)
	{
		cin>>x>>y;
		xp=find(x);
		yp=find(y);
		if(xp==yp)
		continue;
		par[xp]=yp;
		sumw[yp]+=sumw[xp];
		sumb[yp]+=sumb[xp];
	}

	for(i=1;i<=n;i++)
	{
		if(find(i)==i)
		{
			ctr++;
			assign[i]=ctr;
		}
	}
	mem(sumw,0);
	mem(sumb,0);
	for(i=1;i<=n;i++)
	{
		x=find(i);
		x=assign[x];
		store[x].pb(i);
		sumb[x]+=b[i];
		sumw[x]+=w[i];
	}
	for(i=1;i<=ctr;i++)
	{
		for(j=0;j<=limit;j++)
		{
			dp[i][j]=max(dp[i][j],dp[i-1][j]);
			dp[i][j]=max(dp[i][j],dp[i][j-1]);
			if(j>=sumw[i])
			dp[i][j]=max(dp[i][j],dp[i-1][j-sumw[i]]+sumb[i]);
			for(k=0;k<store[i].size();k++)
			{
				x=store[i][k];
				dp[i][j]=max(dp[i][j],dp[i-1][j-w[x]]+b[x]);
			}
		}
	}
	cout<<dp[ctr][limit];
	return 0;
}