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 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h> // int64_t

#define max(a,b) ((a) > (b) ? (a) : (b))
#define min(a,b) ((a) > (b) ? (b) : (a))

int get_int(void) {
  int num;
  scanf("%d", &num);
  return num;
}

int get_int2(int *a1, int *a2) {
  scanf("%d %d", a1, a2);
  return 0;
}

int get_int3(int *a1, int *a2, int *a3) {
  scanf("%d %d %d", a1, a2, a3);
  return 0;
}

#define HASH_SIZE 65536

struct list {
    int num;
    int idx;
    struct list *next;
};

struct list *create_htable(void) {
    static struct list htable[HASH_SIZE];
    int i;
    for(i = 0; i < HASH_SIZE; i++) {
        htable[i].next = &htable[i];
    }
    return htable;
}

int get_key(int num) {
    return num & (HASH_SIZE-1);
}

int find_idx(struct list *htable, int num) {
    struct list *head = &htable[get_key(num)];
    struct list *elem;
    for(elem = head->next; elem != head; elem = elem->next) {
        if(elem->num == num) {
            return elem->idx;
        }
    }
    return -1;
}

void add_elem(struct list *htable, int num, int idx) {
    struct list *elem = malloc(sizeof(struct list));
    struct list *head = &htable[get_key(num)];
    elem->next = head->next;
    elem->num = num;
    elem->idx = idx;
    head->next = elem;
}

struct range {
    int start;
    int end;
};

struct work {
    struct range r;
    int pos;
};

int desc(const void *a1, const void *a2) {
    struct work *w1 = (struct work*)a1;
    struct work *w2 = (struct work*)a2;
    return w2->pos - w1->pos;
}

#define NUM_MAX 200000
#define ROOT_NODE 1
#define QUERY_MAX 200000

#define NUM2_MAX (1<<18)

int upper_bound(int *arr, int size, int key) {
    int low = -1;
    int high = size;
    while(low + 1 < high) {
        int mid = (low + high) / 2;
        if(arr[mid] <= key) {
            low = mid;
        } else {
            high = mid;
        }
    }
    return low;
}

int asc(const void *a1, const void *a2) {
    return *(int*)a1 - *(int*)a2;
}

int compress(struct work *works, int size, int *unzip) {
    int sorted[NUM_MAX*2+50];
    int i;
    for(i = 0; i < size; i++) {
        sorted[i] = works[i].r.start;
    }
    for(i = 0; i < size; i++) {
        sorted[i+size] = works[i].r.end;
    }
    qsort(sorted, size*2, sizeof(int), asc);
    struct list *htable = create_htable();
    int prev = sorted[0]-1;
    // 0-indexed
    int idx = 0;
    for(i = 0; i < size*2; i++) {
        int cur = sorted[i];
        if(prev == cur) continue;
        add_elem(htable, cur, idx);
        unzip[idx] = cur;
        idx++;
        prev = cur;
    }

    // transform in place
    for(i = 0; i < size; i++) {
        struct range r = works[i].r;
        works[i].r.start = find_idx(htable, r.start);
        works[i].r.end = find_idx(htable, r.end);
    }
    return idx;
}


// segtree
int is_overlap(struct range r1, struct range r2) {
    return r1.end > r2.start && r2.end > r1.start;
}

int is_contain(struct range this, struct range box) {
    return box.start <= this.start && this.end <= box.end;
}

void update(int *seg, struct range r, int val, int node, struct range nr) {
    if(!is_overlap(r, nr)) return;
    if(is_contain(nr, r)) {
        // update
        seg[node] = val;
        return;
    }
    struct range left = (struct range){nr.start, (nr.start+nr.end)/2};
    struct range right = (struct range){(nr.start+nr.end)/2, nr.end};
    update(seg, r, val, node*2, left);
    update(seg, r, val, node*2+1, right);
    return;
}

#define INF 0x7f7f7f7f

int get_val(int *seg, int size2, int idx) {
    int node = size2 + idx;
    int ans = INF;
    while(node) {
        ans = min(seg[node], ans);
        node /= 2;
    }
    return ans;
}

int main(void) {
    int num, qs;
    get_int2(&num, &qs);
    static struct work works[NUM_MAX];
    int i;
    for(i = 0; i < num; i++) {
        int start, end, pos;
        get_int3(&start, &end, &pos);
        works[i] = (struct work){
            {max(start-pos, 0), max(0, end-pos)}, pos
        };
    }
    int unzip[NUM_MAX*2+50];
    // 0-indexed
    int size = compress(works, num, unzip);
#ifdef DEBUG
    for(i = 0; i < size; i++) {
        printf("%d: %d\n", i, unzip[i]);
    }
#endif

    int size2 = 1;
    // power of 2
    while(size > size2) size2*= 2;
    qsort(works, num, sizeof(struct work), desc);
    static int seg[NUM2_MAX*2];
    memset(seg, 0x7f, sizeof(int)*(NUM2_MAX*2));

    struct range whole = {0, size2};
    for(i = 0; i < num; i++) {
        struct work w = works[i];
#ifdef DEBUG
        printf("%d, %d to val: %d\n", w.r.start, w.r.end, w.pos);
#endif
        update(seg, w.r, w.pos, ROOT_NODE, whole);
    }

    static int ans[QUERY_MAX];
    int aidx = 0;
    for(i = 0; i < qs; i++) {
        int q = get_int();
        int idx = upper_bound(unzip, size, q);
#ifdef DEBUG
        printf("%d -> idx: %d\n", q, idx);
#endif
        ans[aidx++] = get_val(seg, size2, idx);
    }

    for(i = 0; i < qs; i++) {
        printf("%d\n", ans[i] == INF ? -1 : ans[i]);
    }
    return 0;
}