#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <fstream>
#include <iostream>
#include <algorithm>
#include <bitset>
#include <array>
#include <vector>
#include <queue>
#include <set>
#include <cmath> // 変数名にy1が使えなくなるかも…。
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <limits>
#include <string>

typedef __int128_t int128_t;
std::istream &operator>>(std::istream& input, int128_t& value) { // int128_tの入力。入力が64bitに収まる前提。
    long long tmp; input >> tmp; value = tmp;
    return input;
}
std::ostream &operator<<(std::ostream& output, const int128_t value) { // int128_tの出力。出力が64bitに収まる前提。
    output << (long long)value;
    return output;
}

// range_query
enum RQ_type {
    MAX_MAX, // 更新クエリ: i:[l, r]に対して、x[i] = max(x[i], o). 求値クエリ: i:[l, r]に対して max(x[l],...,x[r]).
    MIN_MIN, // 更新クエリ: i:[l, r]に対して、x[i] = min(x[i], o). 求値クエリ: i:[l, r]に対して min(x[l],...,x[r]).
    ADD_MAX, // 更新クエリ: i:[l, r]に対して、x[i] += o.           求値クエリ: i:[l, r]に対して max(x[l],...,x[r]).
    ADD_MIN, // 更新クエリ: i:[l, r]に対して、x[i] += o.           求値クエリ: i:[l, r]に対して min(x[l],...,x[r]).
    MANUAL, // 手動で任意のものを与える場合。
};

template <RQ_type rqt>
class RQ {
    public:

    int n;
    std::vector<int128_t> data, lazy;
    RQ() {}
    RQ(const int size) {
        // 要素数を2のべき乗にする。
        // kの子をk*2+1,k*2+2とするやり方は、0-index配列に準拠している。1-indexの配列に適用することも考えて、
        // x[0]...x[size]が問題なく確保出来るよう、nはsize+1以上の2冪にする。
        n = 1;
        while (n < size + 1) {
            n *= 2;
        }
        data.resize(n*2, id_val());
        lazy.resize(n*2, id_op());
    }

    // 求値クエリに寄与しない値。
    // op1(v, id_val()) = op1(id_val(), v) = v となるもの。
    int128_t id_val() {
        switch(rqt) {
            case MAX_MAX:
            case ADD_MAX:
                return std::numeric_limits<int64_t>::min();
                // データをint128_tとしているのは、modの取り忘れ等でオーバーフローしないためであり、最大値最小値などは64bitに収まる想定。
                // std::numeric_limits<int128_t>は適切に存在するのか不明なので使わない。
                // 最小値として別の値(0など)を用いるべきケースでは、適切に初期化クエリを行うこと。
                // 加算クエリなら update(1, N, -rq.id_val())、それ以外なら update(1, N, 0)とすれば、[1,N]を0にできる。
            case MIN_MIN:
            case ADD_MIN:
                return std::numeric_limits<int64_t>::max();
            case MANUAL:
                assert(false);
                return 0;
        }
    }

    // 更新操作の単位元。何も更新しない操作。
    // op2(v, id_op()) = v, op3(o, id_op()) = op3(id_op(), o) = o となるもの。
    int128_t id_op() {
        switch(rqt) {
            case MAX_MAX:
                return std::numeric_limits<int64_t>::min();
            case MIN_MIN:
                return std::numeric_limits<int64_t>::max();
            case ADD_MAX:
            case ADD_MIN:
                return 0;
            case MANUAL:
                assert(false);
                return 0;
        }
    }

    // 求値クエリにおいて、2つの値を1つの値に結合する演算。
    int128_t op1(int128_t v1, int128_t v2) {
        switch(rqt) {
            case MAX_MAX:
            case ADD_MAX:
                return std::max(v1, v2);
            case MIN_MIN:
            case ADD_MIN:
                return std::min(v1, v2);
            case MANUAL:
                assert(false);
                return 0;
        }
    }

    // 更新操作
    // 2つの値を結合してから更新操作した値と、2つの値に更新操作してから結合した値が等しい必要がある。すなわち
    // op2(op1(v1, v2), o) = op1(op2(v1, o), op2(v2, o))
    int128_t op2(int128_t v, int128_t o) {
        switch(rqt) {
            case MAX_MAX:
                return std::max(v, o);
            case MIN_MIN:
                return std::min(v, o);
            case ADD_MAX:
            case ADD_MIN:
                return v + o;
            case MANUAL:
                assert(false);
                return 0;
        }
    }

    // 更新操作のマージ
    // 2つの更新操作を2度行った結果と、2つの更新操作を1つにまとめた更新操作を1度行った結果が等しくなる必要がある。すなわち
    // op2(op2(v, o1), o2) = op2(v, op3(o1, o2)) 
    int128_t op3(int128_t o1, int128_t o2) {
        switch(rqt) {
            case MAX_MAX:
                return std::max(o1, o2);
            case MIN_MIN:
                return std::min(o1, o2);
            case ADD_MAX:
            case ADD_MIN:
                return o1 + o2;
            case MANUAL:
                assert(false);
                return 0;
        }
    }

    void push(int k) { // node に対して、lazyの操作を行い、子のノードに伝播する。lazy[k]は単位元に戻す。
        if (lazy[k] == id_op()) { return; }
        if (k < n - 1) {
            lazy[k*2 + 1] = op3(lazy[k*2 + 1], lazy[k]);
            lazy[k*2 + 2] = op3(lazy[k*2 + 2], lazy[k]);
        }
        data[k] = op2(data[k], lazy[k]);
        lazy[k] = id_op();
    }

    // データ配列の区間[a,b)の連結値を求める。
    // k:探索しているセグメント木の節点のセグメント木配列番号
    // [l, r):kに対応する区間
    int128_t query_child(const int a, const int b, const int k, const int l, const int r) {
        if (r <= a || b <= l) { return id_val(); }
        if (a <= l && r <= b) { return op2(data[k], lazy[k]); }
        push(k);

        int128_t vl = query_child(a, b, k*2 + 1, l, (l+r)/2);
        int128_t vr = query_child(a, b, k*2 + 2, (l+r)/2, r);
        return op1(vl, vr);
    }

    // データ配列の区間[a,b]の連結値を求める。query_childと異なり閉区間
    int128_t query(const int a, const int b) {
        return query_child(a, b+1, 0, 0, n);
    }

    // [a, b)の区間に、oで表される演算を行う。
    // k:探索しているセグメント木の節点のセグメント木配列番号
    // [l, r):kに対応する区間
    void update_child(const int a, const int b, const int k, const int l, const int r, int128_t o) {
        if (r <= a || b <= l) { return; }
        if (a <= l && r <= b) { 
            lazy[k] = op3(lazy[k], o);
            return;
        }
        push(k);
        update_child(a, b, k*2 + 1, l, (l+r)/2, o);
        update_child(a, b, k*2 + 2, (l+r)/2, r, o);
        data[k] = op1(op2(data[k*2 + 1], lazy[k*2 + 1]), op2(data[k*2 + 2], lazy[k*2 + 2]));
    } 

    // データ配列の区間[a,b]に、oで表される演算を行う。update_childと異なり閉区間
    void update(const int a, const int b, int128_t o) {
        update_child(a, b+1, 0, 0, n, o);
    }
};

template<typename T>
std::map<T, int> coordinate_compress(const std::vector<T>& vec, const bool reverse = false) {
    // 座標圧縮。要素の小さい順に1-indexで値を割り振る。
    // reverse = trueの場合、大きい順に割り当てるが、mapでの保存順序は常に小さい順である。
    // Tに順序が設定されていればよいので、時間制限の問題が無ければunordered_mapより広い範囲で使える。
    // auto compress = coordinate_compress<T>(...) で利用可能。
    std::vector<T> tmp = vec;
    std::sort(tmp.begin(), tmp.end());
    tmp.erase(std::unique(tmp.begin(), tmp.end()), tmp.end());
    std::map<T, int> mp;
    for (int i = 0; i < tmp.size(); i++) {
        mp[tmp[i]] = reverse ? tmp.size() - i : i + 1;
    }
    return mp;
}

template<typename T>
std::vector<T> coordinate_expand(const std::map<T, int>& mp) {
    // 座標展開。coordinate_compressで圧縮した座標を元の値に戻すための配列を与える。
    // auto expand = coordinate_expand<T>(mp) で利用可能。
    std::vector<T> ret; ret.resize(mp.size()+1);
    for (auto itr = mp.begin(); itr != mp.end(); ++itr) {
        assert(itr->second < ret.size());
        ret[itr->second] = itr->first;
    }
    return ret;
}

const int MAX_N = 200050;
int N, Q;
long long S[MAX_N], T[MAX_N], X[MAX_N];
long long D[MAX_N];
long long ret[MAX_N];

RQ<MIN_MIN> rq = RQ<MIN_MIN>(MAX_N * 4);

int main(int argc, char **argv) {
    std::cin >> N >> Q;

    for (int i = 1; i <= N; i++) {
        std::cin >> S[i] >> T[i] >> X[i];
    }

    for (int i = 1; i <= Q; i++) {
        std::cin >> D[i];
    }

    std::vector<int> tmp;
    for (int i = 1; i <= Q; i++) {
        tmp.push_back(D[i]);
    }
    for (int i = 1; i <= N; i++) {
        tmp.push_back(S[i] - X[i]);
        tmp.push_back(T[i] - X[i] - 1);
    }

    auto compress = coordinate_compress<int>(tmp);
    auto expand = coordinate_expand<int>(compress);

    for (int i = 1; i <= N; i++) {
        rq.update(compress[S[i] - X[i]], compress[T[i] - X[i] - 1], X[i]);
    }

    for (int i = 1; i <= Q; i++) {
        int128_t val = rq.query(compress[D[i]], compress[D[i]]);
        if (val == rq.id_val()) {
            std::cout << -1 << std::endl;
        } else {
            std::cout << val << std::endl;
        }
    }

    return 0;
}


Measured memory_bytes: 106948