import java.util.Scanner

object Main {
  def main(args: Array[String]): Unit = {
    val sc = new Scanner(System.in)
    val N = Integer.parseInt(sc.next())
    val W = Integer.parseInt(sc.next())
    val wv = new Array[(Long, Long)](N)

    for (i <- 0 until N) {
      wv.update(i, (Integer.parseInt(sc.next()).toLong, Integer.parseInt(sc.next()).toLong))
    }

    println(solve(N, W.toLong, wv))
  }

  def solve(N: Int, W: Long, wv: Array[(Long, Long)]): String = {
    val WV = new Array[(Int, Long)](N)
    val W1 = wv(0)._1

    for (i <- 0 until N) {
      WV(i) = (wv(i)._1.toInt, wv(i)._2)
    }

    val W1s = ((0, 0L) +: WV.filter(a => a._1 == W1)).sorted.reverse
    val W2s = ((0, 0L) +: WV.filter(a => a._1 == W1 + 1)).sorted.reverse
    val W3s = ((0, 0L) +: WV.filter(a => a._1 == W1 + 2)).sorted.reverse
    val W4s = ((0, 0L) +: WV.filter(a => a._1 == W1 + 3)).sorted.reverse

    var Max = 0L
    var n1, n2, n3, n4 = 0
    var v1, v2, v3, v4 = 0L
    for (w1 <- W1s) {
      for (w2 <- W2s) {
        for (w3 <- W3s) {
          for (w4 <- W4s) {
            val Weights = W1 * n1 + (W1 + 1) * n2 + (W1 + 2) * n3 + (W1 + 3) * n4
            val Volumes = v1 + v2 + v3 + v4
            if (Weights <= W) {
              Max = Math.max(Max, Volumes)
            }
            if (w4._1 != 0) {
              n4 += 1
              v4 += w4._2
            }
          }
          if (w3._1 != 0) {
            n3 += 1
            v3 += w3._2
          }
          n4 = 0
          v4 = 0L
        }
        if (w2._1 != 0) {
          n2 += 1
          v2 += w2._2
        }
        n3 = 0
        v3 = 0L
      }
      if (w1._1 != 0) {
        n1 += 1
        v1 += w1._2
      }
      n2 = 0
      v2 = 0L
    }
    Max.toString
  }
}