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


  val Array(a, b, k) = readLine.trim.split(' ').map(_.toInt)
  val state = Array.tabulate(a){_ ⇒ Array.tabulate(b){_ ⇒ 0}}
  for (i ← 0 until a){
    val s = readLine.trim.map(_.asDigit)
    for (j ← s.indices){
      state(i)(j) += s(j)
    }
  }
  for (i ← 0 until b){
    val s = readLine.trim.map(_.asDigit)
    for (j ← s.indices){
      state(j)(i) += s(j)
    }
  }
  println(calMinCostFlow(a, b, state, k))

  def calMinCostFlow(aSize: Int, bSize: Int, costs: Array[Array[Int]], k: Int): Int = {
    val start = 0
    val goal = aSize + bSize + 1
    val nodes = Array.tabulate(goal + 1){_ ⇒ ArrayBuffer[Edge]()}.let{a ⇒
      for (i ← 1 to aSize){
        a(i).append(Edge(start, 0, a(start).length, false))
        a(start).append(Edge(i, 0, 0, true))
      }
      for (i ← (aSize + 1) until goal){
        a(i).append(Edge(goal, 0, a(goal).length, true))
        a(goal).append(Edge(i, 0, 0, false))
      }
      for (from ← 0 until aSize; to ← 0 until bSize){
        val i = from + 1
        val j = to + aSize + 1
        a(i).append(Edge(j, costs(from)(to), a(j).length, true))
        a(j).append(Edge(i, -costs(from)(to), a(i).length - 1, false))
      }
      a.map(_.toArray)
    }
    val minCost = Array.tabulate(nodes.length){_ ⇒ Int.MaxValue}.also(_(0) = 0)
    val potential = Array.tabulate(nodes.length){_ ⇒ 0}
    val queue = mutable.PriorityQueue()(Ordering.by[(Int, Int), Int](_._2))
    val prevEdge = Array.tabulate(nodes.length){_ ⇒ nodes(0)(0)}
    var cost = 0
    var count = 0
    var canAddPair = true
    while (canAddPair){
      for (i ← minCost.indices.tail) minCost(i) = Int.MaxValue
      queue.enqueue((0, 0))
      while(queue.nonEmpty){
        val (current, cost) = queue.dequeue()
        if (minCost(current) == cost){
          for (edge ← nodes(current) if edge.canUse) {
            if (minCost(edge.to) > potential(current) + edge.cost - potential(edge.to) + cost) {
              prevEdge(edge.to) = nodes(edge.to)(edge.pair)
              minCost(edge.to) = potential(current) + edge.cost - potential(edge.to) + cost
              queue.enqueue((edge.to, minCost(edge.to)))
            }
          }
        }
      }
      if (minCost(goal) != Int.MaxValue && minCost(goal) + cost <= k){
        cost += minCost(goal)
        count += 1
        var last = goal
        while(last != start){
          val prev = prevEdge(last)
          prev.canUse = true
          nodes(prev.to)(prev.pair).canUse = false
          last = prev.to
        }
        for (i ← 1 until goal) potential(i) += minCost(i)
      }else canAddPair = false
    }
    count
  }
  case class Edge(to: Int, cost: Int, pair: Int, var canUse: Boolean)
  implicit class Scope[T](val value: T) extends AnyVal {
    @inline def also(@inline func: T ⇒ Unit): T = {
      func(value)
      value
    }
    @inline def let[A](@inline func: T ⇒ A): A = func(value)
  }
}
