import java.util.Scanner

object Main extends App { 
  val sc = new Scanner(System.in)
  val N, W = sc.nextInt()
  val ls = (for (i <- 1 to N) yield (sc.nextInt, sc.nextInt, sc.nextInt)).toList

  type Item = (Int,Int) // (value, Weight)

  def mkItems(t:(Int,Int,Int)):List[Item] = {
    def iter(v:Int, w:Int, m:Int, s:Int, acc:List[Item]):(Int, List[Item]) = {
      if (m > 1) {
        iter(v << 1,w << 1,m >> 1, s << 1, (v, w)::acc)
      } else (s,acc)
    }
    val (v,w,m) = t
    val (s, items) = iter(v, w, m, 1, Nil)
    val k = m - (s -1)
    if (k > 0) (v*k,w*k)::items else items
  }
 
  class DP(num:Int, wgt:Int, items:Array[Item]) {
    val memo = Array.fill(wgt+1)(0)
    override def toString:String = (for (e <- memo) yield f" $e%3d").foldLeft("")(_+_)
    def solver():Int = {
      for (i <- 1 to num) {
        val (v, w) = items(i-1)
        for (j <- wgt to 0 by -1) {
          if (j >= w) {
            val v0 = memo(j)
            val v1 = memo(j-w) + v
            memo(j)= v0 max v1
          }
        }
      }
      memo(wgt)
    }
  }
  
  val items = (for (e <- ls) yield mkItems(e)).flatten.toArray

  val dp = new DP(items.length, W, items)
  println(dp.solver())

}
