fun main(args: Array<String>) {
    var (N, W) = pairIntLong()
    val WV = Array(4) { mutableListOf<Long>() }
    var baseW = 0 //WV[0].first.toLong()
    repeat(N) {
        val wv = pairIntLong()
        if (baseW == 0) baseW = wv.first
        WV[wv.first - baseW].add(wv.second)
    }
    WV.forEach {
        it.sortDescending()
        it.add(0, 0)
    }
    var ans = 0L
    for (n0 in WV[0].indices)
    for (n1 in WV[1].indices)
    for (n2 in WV[2].indices)
    for (n3 in WV[3].indices) {
        val w0 = (baseW + 0L) * n0
        val w1 = (baseW + 1L) * n1
        val w2 = (baseW + 2L) * n2
        val w3 = (baseW + 3L) * n3
        if (w0 + w1 + w2 + w3 > W) continue
        val v0 = WV[0].subList(0, n0 + 1).sum()
        val v1 = WV[1].subList(0, n1 + 1).sum()
        val v2 = WV[2].subList(0, n2 + 1).sum()
        val v3 = WV[3].subList(0, n3 + 1).sum()
        ans = Math.max(ans, v0 + v1 + v2 + v3)
    }
    println(ans)
}
fun pairIntLong(offset: Pair<Int, Long> = Pair(0, 0L)) = listOfLong().let { Pair(it[0].toInt() + offset.first, it[1] + offset.second) }

fun next() = readLine()!!
fun listOfString() = next().split(" ")
fun listOfInt() = listOfString().map(String::toInt)
fun listOfLong() = listOfString().map(String::toLong)
