function main(_stdin) {
    const stdin = _stdin.split('\n').filter(e => e.length);
    const [len, maxWeight] = stdin.shift().split(' ').map(Number);
    const items = stdin.map(e => {
        return e.split(' ').map(Number);
    });

    console.log(findMaxVal(items, maxWeight)[0]);
}

/**
 *
 * @param {array} items
 * @param {int} items[0]
 * @param {int} items[1]
 * @param {int} maxWeight
 */
function findMaxVal(items, maxWeight) {
    const table = new Array(maxWeight + 1).fill([0,0]);
    let tableCache = [];

    for (let i = 0, l = items.length; i < l; i++) {
        tableCache = table.slice();
        for (let j = 0; j <= maxWeight; j++) {
            if(j === 0) {
                table[j] = [0, 0];
            } else {
                const item = items[i];

                // 1. items[i][1]がjより小さく、items[i][0]がtable[j][0]より大きい
                table[j] = j >= item[1] && item[0] > table[j][0] ? item.slice() : table[j];

                // 2. items[i]の重さと足してjになるインデックスのtableCacheのvalとitems[i]のvalを足して、table[j]の価値より大きい
                const ref = tableCache[j - item[1]];
                table[j] = ref !== undefined && ref[0] + item[0] > table[j][0] ? [ref[0] + item[0], ref[1] + item[1]] : table[j];

                // 3. items[i]の重さと足してjになるインデックスのtableのvalとitems[i]のvalを足して、table[j]の価値より大きい
                const tableRef = table[j - item[1]];
                table[j] = tableRef !== undefined && tableRef[0] + item[0] > table[j][0] ? [tableRef[0] + item[0], tableRef[1] + item[1]] : table[j];
            }
        }
    }
    return table[maxWeight];
}

main(require('fs').readFileSync('/dev/stdin', 'utf8'));

