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 C# (Mono 4.6.2.0) (judge verdict: Accepted)

#region いつもの
using System;
using System.Collections.Generic;
using System.Linq;
using IEnumerable = System.Collections.IEnumerable;
using IEnumerator = System.Collections.IEnumerator;
using BigInteger = System.Numerics.BigInteger;
using TextReader = System.IO.TextReader;
using static Global;
using static NumGlobal;

static class Global
{
    public static T[] NewArray<T>(int len0, T value) => new T[len0].Fill(value);
    public static T[] NewArray<T>(int len0, Func<T> factory)
    {
        var arr = new T[len0];
        for (int i = 0; i < arr.Length; i++) arr[i] = factory();
        return arr;
    }
    public static T[][] NewArray<T>(int len0, int len1, T value) where T : struct
    {
        var arr = new T[len0][];
        for (int i = 0; i < arr.Length; i++) arr[i] = NewArray(len1, value);
        return arr;
    }
    public static T[][] NewArray<T>(int len0, int len1, Func<T> factory)
    {
        var arr = new T[len0][];
        for (int i = 0; i < arr.Length; i++) arr[i] = NewArray(len1, factory);
        return arr;
    }
    public static T[][][] NewArray<T>(int len0, int len1, int len2, T value) where T : struct
    {
        var arr = new T[len0][][];
        for (int i = 0; i < arr.Length; i++) arr[i] = NewArray(len1, len2, value);
        return arr;
    }
    public static T[][][] NewArray<T>(int len0, int len1, int len2, Func<T> factory)
    {
        var arr = new T[len0][][];
        for (int i = 0; i < arr.Length; i++) arr[i] = NewArray(len1, len2, factory);
        return arr;
    }
    public static T[][][][] NewArray<T>(int len0, int len1, int len2, int len3, T value) where T : struct
    {
        var arr = new T[len0][][][];
        for (int i = 0; i < arr.Length; i++) arr[i] = NewArray(len1, len2, len3, value);
        return arr;
    }
    public static T[][][][] NewArray<T>(int len0, int len1, int len2, int len3, Func<T> factory)
    {
        var arr = new T[len0][][][];
        for (int i = 0; i < arr.Length; i++) arr[i] = NewArray(len1, len2, len3, factory);
        return arr;
    }
    private class ComparerReverseImpl<T> : Comparer<T> where T : IComparable<T> { public override int Compare(T y, T x) => x.CompareTo(y); public override bool Equals(object obj) => obj != null && GetType() == obj.GetType(); public override int GetHashCode() => GetType().GetHashCode(); }
    public static IComparer<T> ComparerReverse<T>() where T : IComparable<T> => new ComparerReverseImpl<T>();
    public static string AllLines<T>(IEnumerable<T> source) => string.Join("\n", source);
    public static string AllJoin<T>(IEnumerable<T> source) => string.Join(" ", source);
}
static class NumGlobal
{
    public static int Pow(int x, int y)
    {
        int res = 1;
        for (; y > 0; y >>= 1)
        {
            if ((y & 1) == 1) res *= x;
            x *= x;
        }
        return res;
    }
    public static BigInteger ParseBigInteger(string s)
    {
        // MonoのBigInteger.Parseが遅いので自前実装
        var res = BigInteger.Zero;
        var splited = new string[(s.Length + 7) / 8];
        for (var i = 0; i < splited.Length - 1; i++)
        {
            splited[i] = s.Substring(8 * i, 8);
        }
        splited[splited.Length - 1] = s.Substring(8 * (splited.Length - 1));
        foreach (var sp in splited)
        {
            res *= (int)Math.Pow(10, sp.Length);
            res += int.Parse(sp);
        }
        return res;
    }
    public static int BitCount(int x) { x -= (x >> 1) & 0x55555555; x = (x & 0x33333333) + ((x >> 2) & 0x33333333); x = (x + (x >> 4)) & 0x0f0f0f0f; x += x >> 8; x += x >> 16; return x & 0x3f; }
    public static int BitCount(long x) { x -= (x >> 1) & 0x5555555555555555; x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333); x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f; x += x >> 8; x += x >> 16; x += x >> 32; return (int)(x & 0x0000007f); }
    public static int MSB(int x) { x |= x >> 1; x |= x >> 2; x |= x >> 4; x |= x >> 8; x |= x >> 16; return BitCount(x) - 1; }
    public static int MSB(long x) { x |= x >> 1; x |= x >> 2; x |= x >> 4; x |= x >> 8; x |= x >> 16; x |= x >> 32; return BitCount(x) - 1; }
    public static int LSB(int x) { x |= x << 1; x |= x << 2; x |= x << 4; x |= x << 8; x |= x << 16; return 32 - BitCount(x); }
    public static int LSB(long x) { x |= x << 1; x |= x << 2; x |= x << 4; x |= x << 8; x |= x << 16; x |= x << 32; return 64 - BitCount(x); }
}
static class Ext
{
    public static T[] Fill<T>(this T[] arr, T value)
    {
        for (var i = 0; i < arr.Length; i++) arr[i] = value;
        return arr;
    }
    public static T[] Sort<T>(this T[] arr)
    {
        Array.Sort(arr);
        return arr;
    }
    public static string[] Sort(this string[] arr)
    {
        Array.Sort(arr, StringComparer.OrdinalIgnoreCase);
        return arr;
    }
    public static T[] Reverse<T>(this T[] arr)
    {
        Array.Reverse(arr);
        return arr;
    }

    public static Tuple<TSource, TMax> MaxBy<TSource, TMax>
        (this IEnumerable<TSource> source, Func<TSource, TMax> maxBySelector)
        where TMax : IComparable<TMax>
    {
        TMax max;
        TSource maxByItem;

        var e = source.GetEnumerator();
        e.MoveNext();
        maxByItem = e.Current;
        max = maxBySelector(maxByItem);
        while (e.MoveNext())
        {
            var item = e.Current;
            var next = maxBySelector(item);
            if (max.CompareTo(next) < 0)
            {
                max = next;
                maxByItem = item;
            }
        }
        return Tuple.Create(maxByItem, max);
    }
    public static Tuple<TSource, TMin> MinBy<TSource, TMin>
        (this IEnumerable<TSource> source, Func<TSource, TMin> minBySelector)
        where TMin : IComparable<TMin>
    {
        TMin min;
        TSource minByItem;

        var e = source.GetEnumerator();
        e.MoveNext();
        minByItem = e.Current;
        min = minBySelector(minByItem);
        while (e.MoveNext())
        {
            var item = e.Current;
            var next = minBySelector(item);
            if (min.CompareTo(next) > 0)
            {
                min = next;
                minByItem = item;
            }
        }
        return Tuple.Create(minByItem, min);
    }
    public static IComparer<T> Reverse<T>(this IComparer<T> comparer) => Comparer<T>.Create((x, y) => comparer.Compare(y, x));
    public static Dictionary<TKey, int> GroupCount<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) => source.GroupBy(keySelector).ToDictionary(g => g.Key, g => g.Count());
    public static Dictionary<TKey, int> GroupCount<TKey>(this IEnumerable<TKey> source) => source.GroupCount(i => i);
}
#pragma warning disable CA1819
[System.Diagnostics.DebuggerNonUserCode]
public class ConsoleReader { private string[] ReadLineSplit() => textReader.ReadLine().Split(Array.Empty<char>(), StringSplitOptions.RemoveEmptyEntries); private string[] line = Array.Empty<string>(); private int linePosition; private TextReader textReader; public ConsoleReader(TextReader tr) { textReader = tr; } public int Int => int.Parse(String); public int Int0 => Int - 1; public long Long => long.Parse(String); public double Double => double.Parse(String); public string String { get { if (linePosition >= line.Length) { linePosition = 0; line = ReadLineSplit(); } return line[linePosition++]; } } public class SplitLine { public SplitLine(ConsoleReader cr) { String = cr.ReadLineSplit(); cr.line = Array.Empty<string>(); } public int[] Int => String.Select(x => int.Parse(x)).ToArray(); public int[] Int0 => String.Select(x => int.Parse(x) - 1).ToArray(); public long[] Long => String.Select(x => long.Parse(x)).ToArray(); public double[] Double => String.Select(x => double.Parse(x)).ToArray(); public string[] String { get; } } public SplitLine Split => new SplitLine(this); public class RepeatReader { ConsoleReader cr; int count; public RepeatReader(ConsoleReader cr, int count) { this.cr = cr; this.count = count; } public T[] Select<T>(Func<ConsoleReader, T> factory) { var arr = new T[count]; for (int i = 0; i < count; i++) arr[i] = factory(cr); return arr; } public string[] String => this.Select(cr => cr.String); public int[] Int => this.Select(cr => cr.Int); public int[] Int0 => this.Select(cr => cr.Int - 1); public long[] Long => this.Select(cr => cr.Long); public double[] Double => this.Select(cr => cr.Double); } public RepeatReader Repeat(int count) => new RepeatReader(this, count); }
public class Program
{
    [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)] private ConsoleReader cr;

    public Program(ConsoleReader consoleReader) { this.cr = consoleReader; }
    static void Main() => Console.WriteLine(new Program(new ConsoleReader(Console.In)).Calc());

    #endregion
    public object Calc()
    {
        var N = cr.Int;
        var Q = cr.Int;

        var sts = new Status[2 * N + Q];
        for (int i = 0; i < N; i++)
        {
            var s = cr.Int;
            var t = cr.Int;
            var x = cr.Int;

            sts[2 * i] = new Status { time = s - x, num = x, ope = Operation.Set };
            sts[2 * i + 1] = new Status { time = t - x, num = x, ope = Operation.Remove };
        }
        for (int q = 0; q < Q; q++)
        {
            var d = cr.Int;
            sts[2 * N + q] = new Status { time = d, num = q, ope = Operation.Query };
        }
        Array.Sort(sts, (s1, s2) =>
        {
            var cmp = s1.time.CompareTo(s2.time);
            if (cmp != 0)
                return cmp;
            return s1.ope.CompareTo(s2.ope);
        });


        var sc = new SortedMultiSet<int>();
        var res = new int[Q];

        for (int i = 0; i < sts.Length; i++)
        {

            if (sts[i].ope == Operation.Remove)
            {
                sc.Remove(sts[i].num);
            }
            else if (sts[i].ope == Operation.Set)
            {
                sc.Add(sts[i].num);
            }
            else
            {
                res[sts[i].num] = sc.Count == 0 ? -1 : sc.First();
            }
        }

        return AllLines(res);
    }
}
struct Status
{
    public int time;
    public Operation ope;
    public int num;
}
enum Operation
{
    Set,
    Remove,
    Query,
}

[System.Diagnostics.DebuggerDisplay("Count = {" + nameof(Count) + "}")]
class SortedMultiSet<TKey> : IEnumerable<TKey>
{
    SortedDictionary<TKey, int> dic;

    public int Count { get; private set; } = 0;

    public void Add(TKey key)
    {
        int val;
        dic.TryGetValue(key, out val);
        dic[key] = val + 1;
        Count++;
    }
    public bool Remove(TKey key)
    {
        int val;
        dic.TryGetValue(key, out val);
        if (val == 0)
            return false;

        if (val == 1)
            dic.Remove(key);
        else
            dic[key] = val - 1;
        Count--;
        return true;
    }

    public IEnumerator<TKey> GetEnumerator()
    {
        foreach (var pair in dic)
            for (int i = 0; i < pair.Value; i++)
                yield return pair.Key;
    }
    IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();

    public SortedMultiSet() { dic = new SortedDictionary<TKey, int>(); }
    public SortedMultiSet(IComparer<TKey> comparer) { dic = new SortedDictionary<TKey, int>(comparer); }
}

static class 二分探索
{
    /// <summary>
    /// 与えられた<paramref name="predicate"/> の結果がtrueであるような最大の数値を二分法で取得します．
    /// </summary>
    /// <param name="l">最小値</param>
    /// <param name="r">最大値</param>
    /// <param name="predicate">判定条件</param>
    /// <returns><paramref name="predicate"/> がtrueを返す最大の o-indexed でのインデックス．</returns>
    /// <remarks> <paramref name="predicate"/> はある範囲以下の全ての数でtrueとなりある範囲以上でfalseとなると仮定します．この関数は O(log N) で実行されます．</remarks>
    static int Bisection(int l, int r, Predicate<int> predicate)
    {
        while (l < r)
        {
            var m = (l + r + 1) >> 1;
            if (predicate(m)) l = m;
            else r = m - 1;
        }
        return l;
    }


    static int BinarySearch<T>(IList<T> a, T v, IComparer<T> cmp, bool isLowerBound)
    {
        var l = 0;
        var r = a.Count - 1;
        while (l <= r)
        {
            var m = (l + r) >> 1;
            var res = cmp.Compare(a[m], v);
            if (res < 0 || (res == 0 && !isLowerBound)) l = m + 1;
            else r = m - 1;
        }
        return l;
    }

    /// <summary>
    /// 与えられた比較関数に従って，<paramref name="a"/> の要素のうち，<paramref name="v"/> 以上の要素であるような最小のインデックスを取得します．
    /// </summary>
    /// <typeparam name="T"><see cref="IList{T}"/> の要素の型を指定します．</typeparam>
    /// <param name="a">対象となるコレクション</param>
    /// <param name="v">対象となる要素</param>
    /// <param name="f"></param>
    /// <returns><paramref name="v"/> 以上の要素であるような最小の o-indexed でのインデックス．</returns>
    /// <remarks> <paramref name="a"/> は比較関数に対して昇順であることを仮定しています．この関数は O(log N) で実行されます．</remarks>
    public static int LowerBound<T>(this IList<T> a, T v, Comparison<T> f) => BinarySearch(a, v, Comparer<T>.Create(f), true);

    /// <summary>
    ///　デフォルトの比較関数に従って，<paramref name="a"/> の要素のうち，<paramref name="v"/> 以上の要素であるような最小のインデックスを取得します．
    /// </summary>
    /// <typeparam name="T"><see cref="IList{T}"/> の要素の型を指定します．</typeparam>
    /// <param name="a">対象となるコレクション</param>
    /// <param name="v">対象となる要素</param>
    /// <param name="f"></param>
    /// <returns><paramref name="v"/> 以上の要素であるような最小の o-indexed でのインデックス．</returns>
    /// <remarks> <paramref name="a"/> は比較関数に対して昇順であることを仮定しています．この関数は O(log N) で実行されます．</remarks>
    public static int LowerBound<T>(this IList<T> a, T v) => BinarySearch(a, v, Comparer<T>.Default, true);

    /// <summary>
    /// 与えられた比較関数に従って，<paramref name="a"/> の要素のうち，<paramref name="v"/> より真に大きい要素が現れる最小のインデックスを取得します．
    /// </summary>
    /// <typeparam name="T"><see cref="IList{T}"/> の要素の型を指定します．</typeparam>
    /// <param name="a">対象となるコレクション</param>
    /// <param name="v">対象となる要素</param>
    /// <param name="f"></param>
    /// <returns><paramref name="v"/> 以上の要素であるような最小の o-indexed でのインデックス．</returns>
    /// <remarks> <paramref name="a"/> は比較関数に対して昇順であることを仮定しています．この関数は O(log N) で実行されます．</remarks>
    public static int UpperBound<T>(this IList<T> a, T v, Comparison<T> cmp) => BinarySearch(a, v, Comparer<T>.Create(cmp), false);

    /// <summary>
    ///　デフォルトの比較関数に従って，<paramref name="a"/> の要素のうち，<paramref name="v"/> より真に大きい要素が現れる最小のインデックスを取得します．
    /// </summary>
    /// <typeparam name="T"><see cref="IList{T}"/> の要素の型を指定します．</typeparam>
    /// <param name="a">対象となるコレクション</param>
    /// <param name="v">対象となる要素</param>
    /// <param name="f"></param>
    /// <returns><paramref name="v"/> 以上の要素であるような最小の o-indexed でのインデックス．</returns>
    /// <remarks> <paramref name="a"/> は比較関数に対して昇順であることを仮定しています．この関数は O(log N) で実行されます．</remarks>
    public static int UpperBound<T>(this IList<T> a, T v) => BinarySearch(a, v, Comparer<T>.Default, false);
}