#include <bits/stdc++.h>
using namespace std;

struct Rect {
    long long A, B, C, D;
};

struct Shot {
    long long x, y, col;
};

struct Event {
    long long x;
    int type; // 0=open, 1=query, 2=close
    int id;
    bool operator < (const Event& other) const {
        if (x != other.x) return x < other.x;
        return type < other.type;
    }
};

struct Edge {
    long long y;
    int type; // 0=bottom, 1=top
    int id;

    bool operator < (const Edge& other) const {
        if (y != other.y) return y < other.y;
        if (type != other.type) return type < other.type;
        return id < other.id;
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N, M;
    cin >> N >> M;

    vector<Rect> rect(N + 1);
    for (int i = 1; i <= N; i++) {
        cin >> rect[i].A >> rect[i].B >> rect[i].C >> rect[i].D;
    }

    vector<Shot> shot(M + 1);
    vector<long long> allColors;

    for (int i = 1; i <= M; i++) {
        cin >> shot[i].x >> shot[i].y >> shot[i].col;
        allColors.push_back(shot[i].col);
    }

    sort(allColors.begin(), allColors.end());
    allColors.erase(unique(allColors.begin(), allColors.end()), allColors.end());

    vector<Event> events;
    events.reserve(2 * N + M);

    for (int i = 1; i <= N; i++) {
        events.push_back({rect[i].A, 0, i});
        events.push_back({rect[i].C, 2, i});
    }

    for (int i = 1; i <= M; i++) {
        events.push_back({shot[i].x, 1, i});
    }

    sort(events.begin(), events.end());

    vector<int> parent(N + 1, 0);
    vector<int> hitSheet(M + 1, 0);

    set<Edge> active;

    for (auto &e : events) {
        if (e.type == 0) {
            int id = e.id;

            auto it = active.lower_bound({rect[id].B, 1, -1});

            if (it != active.end() && it->type == 1)
                parent[id] = it->id;
            else
                parent[id] = 0;

            active.insert({rect[id].B, 0, id});
            active.insert({rect[id].D, 1, id});
        }
        else if (e.type == 1) {
            int id = e.id;

            auto it = active.lower_bound({shot[id].y, 1, -1});

            if (it != active.end() && it->type == 1)
                hitSheet[id] = it->id;
            else
                hitSheet[id] = 0;
        }
        else {
            int id = e.id;
            active.erase({rect[id].B, 0, id});
            active.erase({rect[id].D, 1, id});
        }
    }

    vector<vector<int>> g(N + 1);
    for (int i = 1; i <= N; i++) {
        g[parent[i]].push_back(i);
    }

    vector<pair<int,int>> occ;
    occ.reserve(M);

    for (int i = 1; i <= M; i++) {
        int u = hitSheet[i];
        if (u == 0) continue;

        int c = lower_bound(allColors.begin(), allColors.end(),
                            shot[i].col) - allColors.begin();

        occ.push_back({u, c});
    }

    sort(occ.begin(), occ.end());
    occ.erase(unique(occ.begin(), occ.end()), occ.end());

    vector<vector<int>> nodeColors(N + 1);
    for (auto &p : occ) {
        nodeColors[p.first].push_back(p.second);
    }

    vector<int> order;
    order.reserve(N + 1);

    vector<int> st;
    st.push_back(0);

    while (!st.empty()) {
        int u = st.back();
        st.pop_back();

        order.push_back(u);

        for (int v : g[u]) st.push_back(v);
    }

    vector<unordered_set<int>*> bag(N + 1, nullptr);
    vector<long long> ans(N + 1, 0);

    for (int i = (int)order.size() - 1; i >= 0; i--) {
        int u = order[i];

        auto *cur = new unordered_set<int>();

        for (int c : nodeColors[u]) cur->insert(c);

        for (int v : g[u]) {
            auto *child = bag[v];

            if (cur->size() < child->size())
                swap(cur, child);

            for (int x : *child)
                cur->insert(x);

            delete child;
        }

        bag[u] = cur;
        ans[u] = (long long)cur->size();
    }

    for (int i = 1; i <= N; i++) {
        cout << ans[i] << '\n';
    }

    delete bag[0];
    return 0;
}