local read = setmetatable({}, {__index = function(t, k) local a = {} for i=1,#k do table.insert(a, '*'..string.sub(k, i, i)) end local r = io.read local u = table.unpack or unpack return function() return r(u(a)) end end})
read.N = function(N) local t={} for i=1,N do t[i]=read.n() end return t end
string.totable = function(s) local t={} local u=string.sub for i=1,#s do t[i] = u(s, i, i) end return t end
string.split = function(s) local t={} for w in string.gmatch(s, "[^%s]+") do table.insert(t, w) end return (table.unpack or unpack)(t) end
----
-- Create n dimension array.
local function array(dimension, default_val)
    local n = dimension
    local metatables = {}
    if default_val ~= nil then
        metatables[1] = {__index = function() return default_val end}
    end
    for i=2,n do
        metatables[i] = {__index = function(parent, k)
            local child = setmetatable({}, metatables[i-1])
            rawset(parent, k, child)
            return child
        end}
    end
    return setmetatable({}, metatables[n])
end
----
local N, W = read.nn()
local ws, vs = {}, {}
for i=1,N do
    ws[i] = read.n()
    vs[i] = read.n()
end

-- tbl[n][w]
local tbl = array(2, 0)
tbl[0][0] = 0
for i=0,N-1 do
    for w, _ in pairs(tbl[i]) do
        tbl[i+1][w] = math.max(tbl[i+1][w], tbl[i][w])
        if w+ws[i+1] <= W then
            local cur_val = tbl[i+1][w+ws[i+1]]
            local try_val = tbl[i][w] + vs[i+1]
            tbl[i+1][w+ws[i+1]] = math.max(cur_val, try_val)
        end
    end
end
local ans = 0
for w, _ in pairs(tbl[N]) do
    ans = math.max(ans, tbl[N][w])
end
print(ans)