Problem:
Range Minimum Query (RMQ)

Write a program which manipulates a sequence A = {a0, a1, . . . , an-1} with the following operations:

find(s, t): report the minimum element in as, as+1, . . . ,at.

update(i, x): change ai to x.

Note that the initial values of ai (i = 0, 1, . . . , n−1) are 231-1.

Input

n q
com0 x0 y0
com1 x1 y1
...
comq−1 xq−1 yq−1

In the first line, n (the number of elements in A) and q (the number of queries) are given. Then, q queries are given where com represents the type of queries. '0' denotes update(xi, yi) and '1' denotes find(xi, yi).

Output

For each find operation, print the minimum element.

Constraints

1 ≤ n ≤ 100000

1 ≤ q ≤ 100000

If comi is 0, then 0 ≤ xi < n, 0 ≤ yi < 231-1.

If comi is 1, then 0 ≤ xi < n, 0 ≤ yi < n.

Sample Input 1

3 5
0 0 1
0 1 2
0 2 3
1 0 2
1 1 2

Sample Output 1

1
2

Sample Input 2

1 3
1 0 0
0 0 5
1 0 0

Sample Output 2

2147483647
5

Solution in Kotlin (judge verdict: Accepted)

fun main(args: Array<String>) {
    val (n, q) = readLine()!!.split(' ').map { it.toInt() }
    val queries = (1..q).map {
        readLine()!!.split(' ').map { it.toInt() }
            .let { Query(if (it[0] == 0) QueryType.UPDATE else QueryType.FIND, it[1], it[2]) }
    }

    val infinity = (1L shl 31) - 1
    val segmentTree = SegmentTree(LongArray(n) { infinity }, infinity, Math::min)
    val answer = StringBuilder()

    for (query in queries) {
        val (type, x, y) = query
        when (type) {
            QueryType.UPDATE -> segmentTree[x] = y.toLong()
            QueryType.FIND -> answer.appendln(segmentTree[x..y])
        }
    }

    print(answer)
}

private data class Query(val type: QueryType, val x: Int, val y: Int)
private enum class QueryType { UPDATE, FIND }

private class SegmentTree(init: LongArray, val initValue: Long, val monad: (Long, Long) -> Long) {
    val indices: Int
    val nodes: LongArray

    init {
        var indices = 1
        while (indices < init.size) indices = indices shl 1
        val nodes = LongArray(2 * indices - 1) { initValue }
        for (i in init.indices) nodes[i + indices - 1] = init[i]
        for (i in indices - 2 downTo 0) nodes[i] = monad(nodes[2 * i + 1], nodes[2 * i + 2])
        this.indices = indices
        this.nodes = nodes
    }

    operator fun set(x: Int, value: Long) {
        var index = x + indices - 1
        nodes[index] = value
        while (index > 0) {
            index = (index - 1) / 2
            nodes[index] = monad(nodes[2 * index + 1], nodes[2 * index + 2])
        }
    }

    operator fun get(range: IntRange) = get(range.first, range.last + 1)

    fun get(a: Int, b: Int, k: Int = 0, l: Int = 0, r: Int = indices): Long {
        if (r <= a || b <= l) return initValue
        if (a <= l && r <= b) return nodes[k]
        return monad(
            get(a, b, 2 * k + 1, l, (l + r) / 2),
            get(a, b, 2 * k + 2, (l + r) / 2, r)
        )
    }
}