import java.util

import scala.collection.mutable
import scala.io.StdIn._
object Main extends App {



  val Array(n, x, y) = readLine.trim.split(' ').map(_.toInt)
  val stores = Array.tabulate(n){_ ⇒
    val k = readInt()
    Array.tabulate(k){_ ⇒
      val Array(a, b, c) = readLine.trim.split(' ').map(_.toInt)
      Candy(a, b, c)
    }
  }
  val distance = Array.tabulate(n){_ ⇒ readLine.trim.split(' ').map(_.toInt)}
  val circuit = minCostCircuitCost(distance)
  val prev = calAllSubset((0 until n / 2).map(stores).toArray, y)
  val post = calAllSubset((n / 2 until n).map(stores).toArray, y)
  for (arr ← prev; i ← arr.indices.tail) arr(i) = math.max(arr(i), arr(i - 1))
  for (arr ← post; i ← arr.indices.tail) arr(i) = math.max(arr(i), arr(i - 1))
  val prevSize = n / 2
  var max = 0
  for (i ← circuit.indices if i % 2 == 1 && circuit(i) < x) {
    val f = prev(i % (1 << prevSize))
    val b = post(i >> prevSize)
    val rest = math.min(y, x - circuit(i)).toInt
    for (i ← 0 to rest) {
      if (f(i) + b(rest - i) > max) max = f(i) + b(rest - i)
    }
  }
  println(max)

  def calAllSubset(stores: Array[Array[Candy]], money: Int): Array[Array[Int]] = {
    val result = Array.fill(1 << stores.length){Array.empty[Int]}
    result(0) = Array.fill(money + 1){0}
    for (i ← stores.indices) {
      result(1 << i) = maxSatisfaction(stores(i), money)
    }
    for (i ← 1 until 1 << stores.length) {
      if (i != (i & (~i + 1))) {
        result(i) = merge(result(i & (~i + 1)), result(i - (i & (~i + 1))), money)
      }
    }
    result
  }
  def merge(a: Array[Int], b: Array[Int], money: Int): Array[Int] = {
    val result = a.clone()
    for (i ← a.indices; j ← 1 until b.length - i) {
      result(i + j) = math.max(result(i + j), a(i) + b(j))
    }
    result
  }
  def maxSatisfaction(candies: Array[Candy], money: Int): Array[Int] = {
    val deque= new util.LinkedList[Int]()
    val result = Array.fill(2){Array.fill(money + 1){0}}
    for ((Candy(price, satisfaction, stock), i) ← candies.zipWithIndex) {
      for (r ← 0 until math.min(money + 1, price)) {
        deque.clear()
        for (j ← 0 to (money - r) / price) {
          while (!deque.isEmpty && result(i % 2)(r + deque.peekLast() * price) - deque.peekLast() * satisfaction <= result(i % 2)(r + j * price) - j * satisfaction) deque.pollLast()
          deque.addLast(j)
          while (j - deque.peekFirst() > stock) deque.pollFirst()
          result((i + 1) % 2)(r + j * price) = math.max(result(i % 2)(r + deque.peekFirst() * price) - deque.peekFirst() * satisfaction + j * satisfaction, result(i % 2)(r + j * price))
        }
      }
    }
    result(candies.length % 2)
  }
  case class Candy(price: Int, satisfaction: Int, stock: Int)
  def minCostCircuitCost(costs: Array[Array[Int]]): Array[Long] = {
    val minCost = Array.fill(costs.length){Array.fill(1 << costs.length){Int.MaxValue}}
    val queue = mutable.PriorityQueue[(Flag, Int, Int)]((new Flag(1), 0, 0))(Ordering.by[(Flag, Int, Int), Int](_._3).reverse)
    minCost(0)(1) = 0
    while (queue.nonEmpty) {
      val (flag, current, cost) = queue.dequeue()
      if (minCost(current)(flag.toInt) == cost){
        for (i ← costs.indices) {
          val added = flag + i
          if (minCost(i)(added.toInt) > cost + costs(current)(i)) {
            minCost(i)(added.toInt) = cost + costs(current)(i)
            queue.enqueue((added, i, minCost(i)(added.toInt)))
          }
        }
      }
    }
    val returnCost = minCostTo(costs)
    (0 until (1 << costs.length)).map{f ⇒ returnCost.indices.map{i ⇒ minCost(i)(f) + returnCost(i).toLong}.min}.toArray
  }
  def minCostTo(costs: Array[Array[Int]]): Array[Int] = {
    val queue = mutable.PriorityQueue[(Int, Int)]((0, 0))(Ordering.by[(Int, Int), Int](_._2).reverse)
    val minCost = Array.fill(costs.length){Int.MaxValue}
    minCost(0) = 0
    while(queue.nonEmpty) {
      val (current, cost) = queue.dequeue()
      if (minCost(current) == cost) {
        for (i ← costs.indices) {
          if (minCost(i) > costs(i)(current) + cost) {
            minCost(i) = costs(i)(current) + cost
            queue.enqueue((i, minCost(i)))
          }
        }
      }
    }
    minCost
  }
  class Flag(val toInt: Int = 0) {
    def +(value: Int): Flag = new Flag(toInt | (1 << value))
    def -(value: Int): Flag = new Flag(toInt ^ (1 << value))
    def isOn(value: Int): Boolean = (toInt & (1 << value)) != 0
  }
}


Measured memory_bytes: 278388