import java.io.*;
import java.util.*;

public class Main {
   // 存储并查集中节点 i 的父节点
    private static int[] parent;
    // 存储第 i 朵云(或合并后以 i 为根的商品组)的总价钱
    private static int[] cost;
    // 存储第 i 朵云(或合并后以 i 为根的商品组)的总价值
    private static int[] value;

    public static void main(String[] args) throws IOException {
        // 使用 BufferedReader 和 PrintWriter 提升大规模数据下的 I/O 效率
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));

        // 1. 读取基础配置:n 朵云, m 个搭配关系, w 现有的钱
        String[] strA = br.readLine().trim().split("\\s+");
        int n = Integer.parseInt(strA[0]);
        int m = Integer.parseInt(strA[1]);
        int w = Integer.parseInt(strA[2]);

        parent = new int[n + 1];
        cost = new int[n + 1];
        value = new int[n + 1];

        // 2. 初始化每朵云的属性,并初始化并查集(每个节点初始父节点为自己)
        for (int i = 1; i <= n; i++) {
            String[] strB = br.readLine().trim().split("\\s+");
            cost[i] = Integer.parseInt(strB[0]);
            value[i] = Integer.parseInt(strB[1]);
            parent[i] = i;
        }

        // 3. 处理搭配购买关系:使用并查集将必须一起买的云“联通”起来
        for (int i = 0; i < m; i++) {
            String[] strC = br.readLine().trim().split("\\s+");
            int u = Integer.parseInt(strC[0]);
            int v = Integer.parseInt(strC[1]);
            union(u, v);
        }

        // 4.将同一集合内所有云的价钱和价值全部累加到该集合的“根节点”上
        for (int i = 1; i <= n; i++) {
            int root = find(i);
            // 如果当前节点不是根节点,则将其属性转移给根节点
            if (root != i) {
                cost[root] += cost[i];
                value[root] += value[i];
                // 清空当前非根节点的属性,防止在后续背包计算中被重复统计
                cost[i] = 0;
                value[i] = 0;
            }
        }

        // 5. 执行 0/1 背包算法
        // dp[j] 表示在花费 j 元钱的情况下能获得的最大价值
        int[] dp = new int[w + 1];
        for (int i = 1; i <= n; i++) {
            // 只处理根节点(代表一个完整的“捆绑商品组”)
            if (parent[i] == i) {
                // 0/1 背包内层循环必须“逆序遍历”,防止同一商品被多次购买
                for (int j = w; j >= cost[i]; j--) {
                    // 状态转移方程:不买当前组 vs 买当前组(消耗钱,加价值)
                    dp[j] = Math.max(dp[j], dp[j - cost[i]] + value[i]);
                }
            }
        }

        // 6. 输出预算 w 内能获得的最大总价值
        out.println(dp[w]);

        // 刷新缓冲区并释放资源
        out.flush();
        out.close();
        br.close();
    }

    /**
     * 查找根节点(带路径压缩优化)
     */
    private static int find(int i) {
        if (parent[i] == i) {
            return i;
        }
        // 将查找路径上的所有节点直接挂在根节点下,加速后续查找
        return parent[i] = find(parent[i]);
    }

    /**
     * 合并两个集合
     */
    private static void union(int i, int j) {
        int rootI = find(i);
        int rootJ = find(j);
        if (rootI != rootJ) {
            // 将 I 树合并到 J 树下
            parent[rootI] = rootJ;
        }
    }

}