Problem:
Score : 500 points

Problem Statement

There is an infinitely long street that runs west to east, which we consider as a number line.

There are N roadworks scheduled on this street.
The i-th roadwork blocks the point at coordinate X_i from time S_i - 0.5 to time T_i - 0.5.

Q people are standing at coordinate 0. The i-th person will start the coordinate 0 at time D_i, continue to walk with speed 1 in the positive direction and stop walking when reaching a blocked point.

Find the distance each of the Q people will walk.

Constraints

All values in input are integers.

1 \leq N, Q \leq 2 \times 10^5

0 \leq S_i < T_i \leq 10^9

1 \leq X_i \leq 10^9

0 \leq D_1 < D_2 < ... < D_Q \leq 10^9

If i \neq j and X_i = X_j, the intervals [S_i, T_i) and [S_j, T_j) do not overlap.

Input

Input is given from Standard Input in the following format:

N Q
S_1 T_1 X_1
:
S_N T_N X_N
D_1
:
D_Q

Output

Print Q lines. The i-th line should contain the distance the i-th person will walk or -1 if that person walks forever.

Sample Input 1

4 6
1 3 2
7 13 10
18 20 13
3 4 2
0
1
2
3
5
8

Sample Output 1

2
2
10
-1
13
-1

The first person starts coordinate 0 at time 0 and stops walking at coordinate 2 when reaching a point blocked by the first roadwork at time 2.

The second person starts coordinate 0 at time 1 and reaches coordinate 2 at time 3. The first roadwork has ended, but the fourth roadwork has begun, so this person also stops walking at coordinate 2.

The fourth and sixth persons encounter no roadworks while walking, so they walk forever. The output for these cases is -1.

Solution in Kotlin (1.0.0) (judge verdict: Time Limit Exceeded)

import java.util.*

private data class Work(val start: Int, val end: Int, val dist: Int)
private data class Position(val pos: Int, val index: Int)

fun main(args: Array<String>) {

    /**
     * TreeSet を用いてみる
     * ・重複のない要素を追加可能
     * ・要素の検索，追加．削除が O(logN) で可能
     * ・LinkedList, ArrayList だと追加・削除の操作に O(N) かかってしまう
     * ・最後に答えを出力する際に，特定の開始点での値の検索が必要だが O(NlogN) で終わる
     *
     * HashMap を使う場合は
     * ・重複のない要素を管理可能
     * ・要素の検索，追加，削除は O(1) で可能？？
     * ・最後に答えを出力する際にもO(N) で可能
     * ・特定の工事期間に収まるもの という範囲の探索ができないか．．別配列で持ったりする必要がありそう -> 探索範囲を狭められない -> TreeMapで
     *
     * インデックスがついていない Map, Set をどうやって binarySearch するのか？ setはついていそう？？
     * 毎回 O(logN) で範囲に含まれる値を探す & O(logN) で削除　を繰り返す？？ O(logN) + O(logN) だから問題ないか？？
     * TreeSet, TreeMap には Iterator がありそう -> 値を探す手間が省けるか
     *
     * 特定の位置の iterator を探すには？？？ -> 結局iterator を O(N) 動かさなくては行けないとするなら毎回 O(logN) で探したほうが良さそう
     * -> 特定に位置の iterator を探すには TreeSet().tailSet(element).iterator() で,ある Element以降の TreeSetを作成して，その先頭イテレータを取得すれば良い
     * tailSet はビューを返すので，コピーに時間・空間計算量はほぼ無い & 取得したイテレータに対して操作を行えば，元の TreeSet の要素も更新される
     *
     *
     * TreeMap, TreeSet のどちらを使うかは，値をどの様に格納したいか次第
     *
     * この場合でも TLE ( 若干早くはなっていたがそれでも ☓ なぜ？？
     *
     */

    val (n, q) = readLine()!!.split(" ").map { it.toInt() }

    // 工事を格納 O(N)
    var workList = mutableListOf<Work>()

    for (i in 0 until n) {
        val (s, t, x) = readLine()!!.split(" ").map { it.toInt() }

        // 切り上げ，切り捨てをして閉区間で考える
        var start = Math.ceil(s - 0.5 - x).toInt()
        var end = Math.floor(t - 0.5 - x).toInt()

        workList.add(Work(start, end, x))
    }

    // 工事を距離が近い順にソート O(NlogN)
    workList.sortBy { it.dist }

    // スタート地点を配列に保持する（最初からソートされて渡されるのでソートの必要なし） O(N)
    // スタート地点の中で，ある工事区間に含まれるものを取り出し，配列から削除,
    var posList = TreeSet<Position> { a, b -> a.pos - b.pos } // Comparator をラムダ式で渡す
    for (i in 0 until q) {
        posList.add(Position(readLine()!!.toInt(), i))
    }


    // 答えにはデフォルトで -1 を設定 (選ばれなかったものは工事に合わない = -1 )
    val ans = IntArray(q) { -1 }

    // O(N) のループを通じて O(NlogN + M) の計算量 なはず．．．
    for (work in workList) {

        // あれ，もしかしてここ O(N) ? いや O(1)
//        val work = workList[i]

        // work.start よりも大きな開始地点を持つ posList 内の 最初の要素を指す イテレータを取得
        // O(logN)
        val iter = posList.tailSet(Position(work.start, -1)).iterator()

        // 工事に含まれる位置にいる posList の要素を取得し，削除
        while (true) {

            if (!iter.hasNext()) {
                break
            }

            val position = iter.next()

            if (position.pos > work.end) {
                break
            }

            // O(1)
            ans[position.index] = work.dist

            // O(logN)
            iter.remove()
        }
    }

    for (a in ans) {
        println(a)
    }
}