/*
*
* 思路,将点拓展为三维(x, y, z) z为1表示是查询中的点,z为0表示原来图上就已经有的点,
* 每一个查询都对应的是二维差分问题,关键问题就是怎么对一个坐标点(x, y), 求xi <= x
* 且 yi <= y的所有点的权值和,若加上z这一维度,刚好是对z=1的点(x, y, z), 求所有的
* xi <= x and y1 <= y and zi = 0 的所有点的权值和,这样就可以转成CDQ分治来做了
*
*/
#include <stdio.h>
#include <string.h>
#include <map>
#include <algorithm>
using namespace std;
const int MAX_NODE_NUM = 1000000;
// 三元组,表示三个维度属性值
struct Node {
int a, b; // a, b对应 x, y坐标
int c; // c数值为0, 1, 0表示原来图上存在的点,1表示询问中涉及到的点
long long sum; // 在当前点左下角的所有c为0的点的权值和
long long wei; // 点权值
bool operator < (const Node& other) const {
if (a != other.a) return a < other.a;
if (b != other.b) return b < other.b;
return c < other.c;
}
bool operator == (const Node& other) {
return a == other.a && b == other.b && c == other.c;
}
} buf[1000000], merge_buf[1000000], q[1000000]; // buf是输入数据的缓存,也是结果缓存,merge_buf是归并排序时候使用的额外缓存
void merge_sort(int ll, int rr) {
if (ll == rr) {
return;
}
int mid = (ll + rr) >> 1;
merge_sort(ll, mid);
merge_sort(mid+1, rr);
int ii = ll - 1;
int pos = -1;
long long tot = 0;
for (int jj = mid + 1; jj <= rr; jj++) {
while (ii+1 <= mid && buf[ii+1].b <= buf[jj].b) {
ii += 1;
if (buf[ii].c == 0) {
tot += buf[ii].wei;
}
merge_buf[++pos] = buf[ii];
}
if (buf[jj].c == 1) {
buf[jj].sum += tot;
}
merge_buf[++pos] = buf[jj];
}
while (ii+1 <= mid) {
ii += 1;
merge_buf[++pos] = buf[ii];
}
// 子区间合并
for (int i = ll; i <= rr; i++) {
buf[i] = merge_buf[i-ll];
}
}
// n是输入的三元组数组的长度
void cdq(int n) {
sort(buf, buf + n);
merge_sort(0, n-1);
}
int ans[1000000];
int main() {
// freopen("/Users/grh/Programming/CLionProjects/SimpleTest/input.txt", "r", stdin);
int n, m;
int a, b, w;
scanf("%d %d", &n, &m);
int pos = 0;
for (int i = 0; i < n; i++) {
scanf("%d %d %lld", &(buf[pos].a), &(buf[pos].b), &(buf[pos].wei));
buf[pos].c = 0;
buf[pos].sum = 0;
pos += 1;
}
int x1, y1, x2, y2;
int q_pos = 0;
for (int i = 0; i < m; i++) {
scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
if (x1 > x2) {
swap(x1, x2);
}
if (y1 > y2) {
swap(y1, y2);
}
buf[pos].a = x2, buf[pos].b = y2, buf[pos].c = 1;
buf[pos].wei = 0, buf[pos].sum = 0;
q[q_pos++] = buf[pos];
pos += 1;
buf[pos].a = x1-1, buf[pos].b = y2, buf[pos].c = 1;
buf[pos].wei = 0, buf[pos].sum = 0;
q[q_pos++] = buf[pos];
pos += 1;
buf[pos].a = x2, buf[pos].b = y1-1, buf[pos].c = 1;
buf[pos].wei = 0, buf[pos].sum = 0;
q[q_pos++] = buf[pos];
pos += 1;
buf[pos].a = x1-1, buf[pos].b = y1-1, buf[pos].c = 1;
buf[pos].wei = 0, buf[pos].sum = 0;
q[q_pos++] = buf[pos];
pos += 1;
}
cdq(pos);
map<Node, long long> nodes;
for (int i = 0; i < pos; i++) {
if (buf[i].c == 1) {
nodes[buf[i]] = buf[i].sum;
}
}
// 用矩形的四个关键点来进行差分计算
for (int i = 0; i < q_pos >> 2; i++) {
long long tot = 0;
tot += nodes[q[i * 4]];
tot -= nodes[q[i * 4 + 1]];
tot -= nodes[q[i * 4 + 2]];
tot += nodes[q[i * 4 + 3]];
printf("%lld\n", tot);
}
return 0;
}