#include <bits/stdc++.h>
using namespace std;
const long long M = 1e9 + 7;
const long long mod = 998244353;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
const int maxn = 1e6 + 5;
const int INF = 0;
template <class T>
class SegmentTree {
 public:
  T t[4 * maxn];
  void update(int p, T x, int cur = 1, int L = 0, int R = maxn - 1) {
    if (L == R) {
      t[cur] += x;
      return;
    }
    int mid = L + R >> 1;
    if (p <= mid)
      update(p, x, cur * 2, L, mid);
    else
      update(p, x, cur * 2 + 1, mid + 1, R);
    t[cur] = t[cur * 2] + t[cur * 2 + 1];
  }
  T query(int l, int r, int cur = 1, int L = 0, int R = maxn - 1) {
    if (R < l or L > r) return INF;
    if (L >= l && R <= r) {
      return t[cur];
    }
    int mid = L + R >> 1;
    return query(l, r, cur * 2, L, mid) + query(l, r, cur * 2 + 1, mid + 1, R);
  }
};
struct line {
  int v, l, r;
  void read() { cin >> v >> l >> r; }
};
const int sz = 1e6;
SegmentTree<long long> tree;
void solve() {
  int n, m;
  cin >> n >> m;
  vector<line> ver(m);
  vector<pair<int, int> > op, cl;
  long long ans = 0;
  for (int i = 0; i < n; i++) {
    int v, l, r;
    cin >> v >> l >> r;
    op.push_back({l, v});
    cl.push_back({r, v});
    if (l == 0 && r == sz) {
      ans++;
    }
  }
  for (line &y : ver) y.read();
  sort(ver.begin(), ver.end(), [&](line a, line b) { return a.v < b.v; });
  int l = 0, r = 0;
  sort(op.begin(), op.end());
  sort(cl.begin(), cl.end());
  for (line &y : ver) {
    while (l < cl.size() && cl[l].first < y.v) {
      tree.update(cl[l].second, -1);
      l++;
    }
    while (r < op.size() && op[r].first <= y.v) {
      tree.update(op[r].second, 1);
      r++;
    }
    ans += tree.query(y.l, y.r);
    if (y.l == 0 && y.r == sz) ans++;
  }
  cout << ans + 1 << "\n";
}
int32_t main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int t = 1;
  while (t--) {
    solve();
  }
}
