#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline bool chkmin(T &x, T y) {
  return y < x ? x = y, 1 : 0;
}
template <typename T>
inline bool chkmax(T &x, T y) {
  return x < y ? x = y, 1 : 0;
}
const int INF = 0x3f3f3f3f;
const int N = 3e5 + 10;
set<int> Set;
struct node {
  int pos, id;
  bool operator<(const node &rhs) const {
    return pos == rhs.pos ? id < rhs.id : pos < rhs.pos;
  }
} Opt[N << 1], Hash[N];
struct Q {
  int val, id;
  bool operator<(const Q &rhs) const { return val < rhs.val; }
} Query[N];
int val[N], Other[N], Single[N], ans[N], id[N], Lim[N];
unordered_map<int, int> Len[N];
inline int read() {
  int x = 0, flag = 1;
  char ch = getchar();
  while (!isdigit(ch) && ch != '-') ch = getchar();
  if (ch == '-') flag = -1, ch = getchar();
  while (isdigit(ch)) x = (x << 3) + (x << 1) + (ch - '0'), ch = getchar();
  return x * flag;
}
struct Segment_Tree {
  int Max[N << 2];
  inline void Modify(int o, int l, int r, int pos, int Val) {
    if (l == r) {
      Max[o] = Val;
      return;
    }
    if (pos <= ((l + r) >> 1))
      Modify(o << 1, l, ((l + r) >> 1), pos, Val);
    else
      Modify(o << 1 | 1, ((l + r) >> 1) + 1, r, pos, Val);
    Max[o] = max(Max[o << 1], Max[o << 1 | 1]);
  }
  inline int Query(int o, int l, int r, int L, int R) {
    if (L > R) return 0;
    if (L <= l && r <= R) return Max[o];
    int res = 0;
    if (L <= ((l + r) >> 1))
      chkmax(res, Query(o << 1, l, ((l + r) >> 1), L, R));
    if (R > ((l + r) >> 1))
      chkmax(res, Query(o << 1 | 1, ((l + r) >> 1) + 1, r, L, R));
    return res;
  }
} T;
int main() {
  int n = read(), C = read(), cnt = 0;
  for (int i = (1), iend = (n); i <= iend; i++) {
    int l = read(), r = read();
    val[i] = read();
    Opt[++cnt] = (node){l, i}, Opt[++cnt] = (node){r, -i};
    Hash[i] = (node){val[i], i};
  }
  Opt[++cnt] = (node){INF << 1, 0};
  int q = read();
  for (int i = (1), iend = (q); i <= iend; i++) {
    int v = read();
    Query[i] = (Q){v, i};
  }
  sort(Hash + 1, Hash + n + 1);
  for (int i = (1), iend = (n); i <= iend; i++)
    Lim[i] =
        upper_bound(Hash + 1, Hash + n + 1, (node){C - val[i], INF}) - Hash - 1;
  for (int i = (1), iend = (n); i <= iend; i++)
    id[i] = lower_bound(Hash + 1, Hash + n + 1, (node){val[i], i}) - Hash;
  sort(Opt + 1, Opt + cnt + 1);
  sort(Query + 1, Query + q + 1);
  int top = 0, pos = 1, sum = 0, tot = 0;
  for (int i = (1), iend = (cnt); i <= iend; i++) {
    int cur = Opt[i].pos - Opt[i - 1].pos;
    if (top == 0)
      sum += cur;
    else {
      int l = *Set.begin(), r = *(--Set.end());
      if (top == 1 && val[l] <= C) {
        Single[l] += cur;
        int Val = max(T.Query(1, 1, n, 1, min(Lim[l], id[l] - 1)),
                      T.Query(1, 1, n, id[l] + 1, Lim[l]));
        chkmax(tot, max(Val, Other[l]) + Single[l]);
        T.Modify(1, 1, n, id[l], Single[l]);
      } else if (top == 2 && val[l] + val[r] <= C) {
        Len[l][r] += cur, Len[r][l] += cur;
        chkmax(Other[l], Len[l][r] + Single[r]);
        chkmax(Other[r], Len[l][r] + Single[l]);
        chkmax(tot, Single[l] + Single[r] + Len[l][r]);
      }
    }
    if (Opt[i].id > 0)
      Set.insert(Opt[i].id), top++;
    else
      Set.erase(-Opt[i].id), top--;
    while (pos <= q && sum + tot >= Query[pos].val)
      ans[Query[pos].id] = Opt[i].pos - (sum + tot - Query[pos].val), pos++;
  }
  for (int i = (1), iend = (q); i <= iend; i++) printf("%d\n", ans[i]);
  return 0;
}
