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: Time Limit Exceeded)

/*
csc -debug E.cs && mono --debug E.exe <<< "4 6
1 3 2
7 13 10
18 20 13
3 4 2
0
1
2
3
5
8"
*/

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Reflection;

public class HelloWorld {
    public static void SolveCodeForces() {
        var N = cin.NextInt();
        var Q = cin.NextInt();

        var blockers = new long[N][]; // S, T, X
        for (var i = 0; i < N; i++)
            blockers[i] = cin.LongArray();

        // [time, index]
        var D = new RBTree<long[]>((a,b) => (int)(a[0] - b[0]), a => new Node<long[]>(a));
        for (var i = 0; i < Q; i++)
            D.Insert(new long[] { cin.NextLong(), i });

        var sameTime = new Dictionary<long, List<long[]>>();
        var times = new HashSet<long>();
        foreach (var stx in blockers) {
            var x = stx[2];
            if (!sameTime.ContainsKey(x)) sameTime[x] = new List<long[]>();
            sameTime[x].Add(stx);
            times.Add(x);
        }

        var timesSorted = new List<long>(times);
        timesSorted.Sort();

        var ans = new long[Q];

        foreach (var x in timesSorted) {
            var arr = sameTime[x];
            foreach (var stx in arr) {
                var s = stx[0];
                var t = stx[1];

                var finished = new List<long[]>();

                using(var enumerator = D.GetSuffixEnumerator(new long[] { s - x, 0 }))
                    while(enumerator.MoveNext()) {
                        var item = enumerator.Current.value;
                        var time = item[0];

                        if (time + x >= t)
                            break;

                        finished.Add(item);
                        ans[(int)item[1]] = x;
                    }

                foreach (var fin in finished)
                    D.Remove(fin);

// System.Console.WriteLine(new {s,t,x, finished=string.Join(" ", finished)});
            }
        }

        foreach (var node in D) {
            ans[node.value[1]] = -1;
        }

        foreach (var dist in ans)
            cout.AppendLine(dist.ToString());
    }

    static Scanner cin = new Scanner();
    static StringBuilder cout = new StringBuilder();

    static public void Main () {
        SolveCodeForces();
        // IncreaseStack(SolveCodeForces);
        System.Console.Write(cout.ToString());
    }

    public static void IncreaseStack(ThreadStart action, int stackSize = 128000000)
    {
        var thread = new Thread(action, stackSize);
        thread.Start();
        thread.Join();
    }
}

public static class Helpers {
    public static T[] CreateArray<T>(int length, Func<int, T> itemCreate) {
        var result = new T[length];
        for (var i = 0; i < result.Length; i++)
            result[i] = itemCreate(i);
        return result;
    }
}

public class Scanner
{
    private string[] line = new string[0];
    private int index = 0;

    public string Next() {
        if (line.Length <= index) {
            line = Console.ReadLine().Split(' ');
            index = 0;
        }
        var res = line[index];
        index++;
        return res;
    }

    public int NextInt() {
        return int.Parse(Next());
    }

    public long NextLong() {
        return long.Parse(Next());
    }

    public ulong NextUlong() {
        return ulong.Parse(Next());
    }

    public string[] Array() {
        line = Console.ReadLine().Split(' ');
        index = line.Length;
        return line;
    }

    public int[] IntArray(int emptyPrefixLen = 0) {
        var array = Array();
        var result = new int[emptyPrefixLen + array.Length];
        for (int i = 0; i < array.Length; i++)
            result[emptyPrefixLen + i] = int.Parse(array[i]);
        return result;
    }

    public long[] LongArray() {
        var array = Array();
        var result = new long[array.Length];
        for (int i = 0; i < array.Length; i++)
            result[i] = long.Parse(array[i]);
        return result;
    }

    public ulong[] UlongArray() {
        var array = Array();
        var result = new ulong[array.Length];
        for (int i = 0; i < array.Length; i++)
            result[i] = ulong.Parse(array[i]);
        return result;
    }
}

    public class Node<T> {
        public Node<T> left, right;
        public T value;

        private uint size_black = 2u;

        public Node(T val) {
            value = val;
        }

        public bool IsBlack {
            get { return (size_black & 1u) == 1u; }
            set { size_black = value ? (size_black | 1u) : (size_black & ~1u); }
        }

        public uint Size {
            get { return size_black >> 1; }
            set { size_black = (value << 1) | (size_black & 1u); }
        }

        public uint FixSize()
        {
            Size = 1 + (left != null ? left.Size : 0) + (right != null ? right.Size : 0);
            return Size;
        }

        public void SwapValue (Node<T> other)
        {
            var tmp = value;
            value = other.value;
            other.value = tmp;
        }
    }

	public class RBTree<T> : IEnumerable, IEnumerable<Node<T>> {
		public Node<T> root;

        private Func<T, T, int> compare;
        private Func<T, Node<T>> createNode;

		public RBTree(Func<T, T, int> compare, Func<T, Node<T>> createNode)
		{
			this.compare = compare;
            this.createNode = createNode;
		}

		// returns new node if the value was inserted, existed node if the value already existed in the tree
		public Node<T> Insert(T key)
		{
            var new_node = createNode(key);

			if (root == null) {
				root = new_node;
				root.IsBlack = true;
				return root;
			}

			var path = new List<Node<T>>();
			int in_tree_cmp = find_key(key, path);
			var retval = path[path.Count - 1];
			if (retval == null) {
				retval = do_insert(in_tree_cmp, new_node, path);
			}
			return retval;
		}

		// returns node if the value was removed, null if the value didn't exist in the tree
		public Node<T> Remove(T key)
		{
			if (root == null)
				return null;

			var path = new List<Node<T>>();
			int in_tree_cmp = find_key(key, path);
            return in_tree_cmp == 0 ? do_remove(path) : null;
		}

		public Node<T> Lookup(T key)
		{
			var current = root;
			while (current != null) {
				int c = compare(key, current.value);
				if (c == 0)
					break;
				current = c < 0 ? current.left : current.right;
			}
			return current;
		}

        public bool Contains(T key)
        {
            return Lookup(key) != null;
        }

		public void Bound(T key, out Node<T> lower, out Node<T> upper)
		{
            lower = null;
            upper = null;
			var current = root;
			while (current != null) {
				var c = compare(key, current.value);
				if (c <= 0)
					upper = current;
				if (c >= 0)
					lower = current;
				if (c == 0)
					break;
				current = c < 0 ? current.left : current.right;
			}
		}

		public int Count {
			get { return root == null ? 0 : (int)root.Size; }
		}

        // Returns a count of items lower than (strict) value
        public uint GetCountLowerThan(T val) {
            var ans = 0u;
            var current = root;
            while (current != null) {
                var c = compare(val, current.value);
                if (c >= 0)
                    ans += (c > 0 ? 1u : 0) + (current.left == null ? 0 : current.left.Size);
                if (c == 0)
                    break;
                current = c < 0 ? current.left : current.right;
            }
            return ans;
        }

		public Node<T> this[int index] {
			get {
				if (index < 0 || index >= Count)
					throw new IndexOutOfRangeException("index");

				var current = root;
				while (current != null) {
					int left_size = current.left == null ? 0 : (int)current.left.Size;
					if (index == left_size)
						return current;
					if (index < left_size) {
						current = current.left;
					} else {
						index -= left_size + 1;
						current = current.right;
					}
				}
				throw new SystemException("Internal Error: index calculation");
			}
		}

		public NodeEnumerator GetEnumerator()
		{
			return new NodeEnumerator (this);
		}

		// Get an enumerator that starts at 'key' or the next higher element in the tree
		public NodeEnumerator GetSuffixEnumerator(T key)
		{
			var pennants = new Stack<Node<T>>();
			var current = root;
			while (current != null) {
				int c = compare(key, current.value);
				if (c <= 0)
					pennants.Push(current);
				if (c == 0)
					break;
				current = c < 0 ? current.left : current.right;
			}
			return new NodeEnumerator(this, pennants);
		}

		IEnumerator<Node<T>> IEnumerable<Node<T>>.GetEnumerator()
		{
			return GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}

		// Pre-condition: root != null
		int find_key(T key, List<Node<T>> path)
		{
			int c = 0;
			Node<T> sibling = null;
			Node<T> current = root;

			if (path != null)
				path.Add(root);

			while (current != null) {
				c = compare(key, current.value);
				if (c == 0)
					return c;

				if (c < 0) {
					sibling = current.right;
					current = current.left;
				} else {
					sibling = current.left;
					current = current.right;
				}

				if (path != null) {
					path.Add(sibling);
					path.Add(current);
				}
			}

			return c;
		}

		Node<T> do_insert(int in_tree_cmp, Node<T> current, List<Node<T>> path)
		{
			path[path.Count - 1] = current;
			var parent = path[path.Count - 3];

			if (in_tree_cmp < 0)
				parent.left = current;
			else
				parent.right = current;
			for (int i = 0; i < path.Count - 2; i += 2)
				++ path[i].Size;

			if (!parent.IsBlack)
				rebalance_insert(path);

			if (!root.IsBlack)
				throw new SystemException("Internal error: root is not black");

			return current;
		}

		Node<T> do_remove(List<Node<T>> path)
		{
			int curpos = path.Count - 1;

			var current = path[curpos];
			if (current.left != null) {
				var pred = right_most (current.left, current.right, path);
				current.SwapValue (pred);
				if (pred.left != null) {
					var ppred = pred.left;
					path.Add(null); path.Add(ppred);
					pred.SwapValue (ppred);
				}
			} else if (current.right != null) {
				var succ = current.right;
				path.Add(null); path.Add(succ);
				current.SwapValue (succ);
			}

			curpos = path.Count - 1;
			current = path[curpos];

			if (current.Size != 1)
				throw new SystemException("Internal Error: red-black violation somewhere");

			// remove it from our data structures
			path[curpos] = null;
			node_reparent(curpos == 0 ? null : path[curpos-2], current, 0, null);

			for (int i = 0; i < path.Count - 2; i += 2)
				-- path[i].Size;

			if (current.IsBlack) {
				current.IsBlack = false;
				if (curpos != 0)
					rebalance_delete(path);
			}

			if (root != null && !root.IsBlack)
				throw new SystemException("Internal Error: root is not black");

			return current;
		}

		// Pre-condition: current is red
		void rebalance_insert(List<Node<T>> path)
		{
			int curpos = path.Count - 1;
			do {
				// parent == curpos-2, uncle == curpos-3, grandpa == curpos-4
				if (path[curpos-3] == null || path[curpos-3].IsBlack) {
					rebalance_insert__rotate_final (curpos, path);
					return;
				}

				path[curpos-2].IsBlack = path[curpos-3].IsBlack = true;

				curpos -= 4; // move to the grandpa

				if (curpos == 0) // => current == root
					return;
				path[curpos].IsBlack = false;
			} while (!path[curpos-2].IsBlack);
		}

		// Pre-condition: current is black
		void rebalance_delete(List<Node<T>> path)
		{
			int curpos = path.Count - 1;
			do {
				var sibling = path[curpos-1];
				// current is black => sibling != null
				if (!sibling.IsBlack) {
					// current is black && sibling is red
					// => both sibling.left and sibling.right are black, and are not null
					curpos = ensure_sibling_black (curpos, path);
					// one of the nephews became the new sibling -- in either case, sibling != null
					sibling = path[curpos-1];
				}

				if ((sibling.left != null && !sibling.left.IsBlack) ||
				    (sibling.right != null && !sibling.right.IsBlack)) {
					rebalance_delete__rotate_final (curpos, path);
					return;
				}

				sibling.IsBlack = false;

				curpos -= 2; // move to the parent

				if (curpos == 0)
					return;
			} while (path[curpos].IsBlack);
			path[curpos].IsBlack = true;
		}

		void rebalance_insert__rotate_final (int curpos, List<Node<T>> path)
		{
			var current = path[curpos];
			var parent = path[curpos-2];
			var grandpa = path[curpos-4];

			uint grandpa_size = grandpa.Size;

		    Node<T> new_root;

			bool l1 = parent == grandpa.left;
			bool l2 = current == parent.left;
			if (l1 && l2) {
				grandpa.left = parent.right; parent.right = grandpa;
				new_root = parent;
			} else if (l1 && !l2) {
				grandpa.left = current.right; current.right = grandpa;
				parent.right = current.left; current.left = parent;
				new_root = current;
			} else if (!l1 && l2) {
				grandpa.right = current.left; current.left = grandpa;
				parent.left = current.right; current.right = parent;
				new_root = current;
			} else { // (!l1 && !l2)
				grandpa.right = parent.left; parent.left = grandpa;
				new_root = parent;
			}

			grandpa.FixSize(); grandpa.IsBlack = false;
			if (new_root != parent)
				parent.FixSize(); /* parent is red already, so no need to set it */

			new_root.IsBlack = true;
			node_reparent(curpos == 4 ? null : path[curpos-6], grandpa, grandpa_size, new_root);
		}

		// Pre-condition: sibling is black, and one of sibling.left and sibling.right is red
		void rebalance_delete__rotate_final (int curpos, List<Node<T>> path)
		{
			//Node current = path[curpos];
			var sibling = path[curpos-1];
			var parent = path[curpos-2];

			uint parent_size = parent.Size;
			bool parent_was_black = parent.IsBlack;

			Node<T> new_root;
			if (parent.right == sibling) {
				// if far nephew is black
				if (sibling.right == null || sibling.right.IsBlack) {
					// => near nephew is red, move it up
					var nephew = sibling.left;
					parent.right = nephew.left; nephew.left = parent;
					sibling.left = nephew.right; nephew.right = sibling;
					new_root = nephew;
				} else {
					parent.right = sibling.left; sibling.left = parent;
					sibling.right.IsBlack = true;
					new_root = sibling;
				}
			} else {
				// if far nephew is black
				if (sibling.left == null || sibling.left.IsBlack) {
					// => near nephew is red, move it up
					var nephew = sibling.right;
					parent.left = nephew.right; nephew.right = parent;
					sibling.right = nephew.left; nephew.left = sibling;
					new_root = nephew;
				} else {
					parent.left = sibling.right; sibling.right = parent;
					sibling.left.IsBlack = true;
					new_root = sibling;
				}
			}

			parent.FixSize(); parent.IsBlack = true;
			if (new_root != sibling)
				sibling.FixSize(); /* sibling is already black, so no need to set it */

			new_root.IsBlack = parent_was_black;
			node_reparent(curpos == 2 ? null : path[curpos-4], parent, parent_size, new_root);
		}

		// Pre-condition: sibling is red (=> parent, sibling.left and sibling.right are black)
		int ensure_sibling_black(int curpos, List<Node<T>> path)
		{
			var current = path[curpos];
			var sibling = path[curpos-1];
			var parent = path[curpos-2];

			bool current_on_left;
			uint parent_size = parent.Size;

			if (parent.right == sibling) {
				parent.right = sibling.left; sibling.left = parent;
				current_on_left = true;
			} else {
				parent.left = sibling.right; sibling.right = parent;
				current_on_left = false;
			}

			parent.FixSize(); parent.IsBlack = false;

			sibling.IsBlack = true;
			node_reparent(curpos == 2 ? null : path[curpos-4], parent, parent_size, sibling);

			// accomodate the rotation
			if (curpos+1 == path.Count) {
				path.Add(null);
				path.Add(null);
			}

			path[curpos-2] = sibling;
			path[curpos-1] = current_on_left ? sibling.right : sibling.left;
			path[curpos] = parent;
			path[curpos+1] = current_on_left ? parent.right : parent.left;
			path[curpos+2] = current;

			return curpos + 2;
		}

		void node_reparent(Node<T> orig_parent, Node<T> orig, uint orig_size, Node<T> updated)
		{
			if (updated != null && updated.FixSize() != orig_size)
				throw new SystemException("Internal error: rotation");

			if (orig == root)
				root = updated;
			else if (orig == orig_parent.left)
				orig_parent.left = updated;
			else if (orig == orig_parent.right)
				orig_parent.right = updated;
			else
				throw new SystemException("Internal error: path error");
		}

		// Pre-condition: current != null
		static Node<T> right_most(Node<T> current, Node<T> sibling, List<Node<T>> path)
		{
			for (;;) {
				path.Add(sibling);
				path.Add(current);
				if (current.right == null)
					return current;
				sibling = current.left;
				current = current.right;
			}
		}

		public struct NodeEnumerator : IEnumerator, IEnumerator<Node<T>> {
			RBTree<T> tree;

			Stack<Node<T>> pennants, init_pennants;

			internal NodeEnumerator (RBTree<T> tree)
				: this()
			{
				this.tree = tree;
			}

			internal NodeEnumerator (RBTree<T> tree, Stack<Node<T>> init_pennants)
				: this (tree)
			{
				this.init_pennants = init_pennants;
			}

			public void Reset()
			{
				pennants = null;
			}

			public Node<T> Current {
				get { return pennants.Peek(); }
			}

			object IEnumerator.Current {
				get {
					return Current;
				}
			}

			public bool MoveNext()
			{
				Node<T> next;
				if (pennants == null) {
					if (tree.root == null)
						return false;
					if (init_pennants != null) {
						pennants = init_pennants;
						init_pennants = null;
						return pennants.Count != 0;
					}
					pennants = new Stack<Node<T>>();
					next = tree.root;
				} else {
					if (pennants.Count == 0)
						return false;
					var current = pennants.Pop();
					next = current.right;
				}
				for (; next != null; next = next.left)
					pennants.Push(next);

				return pennants.Count != 0;
			}

			public void Dispose()
			{
				tree = null;
				pennants = null;
			}
		}
	}