fun main(args: Array<String>) {
    val (N, H) = readLine()!!.split(" ").map { it.toInt() }
    val ab = mutableListOf<Pair<Int, Int>>()
    (1..N).forEach {
        val (a, b) = readLine()!!.split(" ").map { it.toInt() }
        ab.add(Pair(a, b))
    }

    // 後ろから考えるのはありやな
    // Basically, we should use the best brade.
    // O(N)
    val maxA = ab.maxBy { it.first }!!.first
    // If there is a goog brade which can hit damage bigger than maxA by throging, we should also use it
    // O(N)
    val bradesShouldBeThrown = ab.map { it.second }.filter { it > maxA }.sortedDescending()
    // We can consider throwing first actually even if one of them is same as maxA, because the order can be changed later.
    // O(N)
    var totalDamege = 0L
    var attackCount = 0
    bradesShouldBeThrown.forEach {
        totalDamege += it
        attackCount++
        if (totalDamege >= H) {
            println(attackCount)
            return
        }
    }

    val remainders = H - totalDamege
    attackCount += Math.ceil(remainders.toDouble() / maxA.toDouble()).toInt()

    println(attackCount)
}
