#include <bits/stdc++.h>
using namespace std;
template <class T>
bool ckmin(T& a, const T& b) {
  return b < a ? a = b, 1 : 0;
}
template <class T>
bool ckmax(T& a, const T& b) {
  return a < b ? a = b, 1 : 0;
}
template <class T, int sz>
struct BIT {
  T b[sz + 1];
  BIT() {
    for (int i = 0; i < sz + 1; i++) b[i] = 0;
  }
  void add(int k, T val) {
    k++;
    for (; k <= sz; k += (k & -k)) b[k] += val;
  }
  T psum(int ind) {
    T ans = 0;
    ind++;
    for (; ind > 0; ind -= (ind & -ind)) ans += b[ind];
    return ans;
  }
  T sum(int l, int r) { return psum(r) - psum(l - 1); }
  void upd(int l, int r, T val) {
    add(l, val);
    if (r != sz - 1) add(r + 1, -val);
  }
  T query(int idx) { return psum(idx); }
};
const int MX = 1000005;
const int MAX_N = 100005;
int numH, numV;
pair<int, pair<int, int> > horiz[MAX_N];
pair<int, pair<int, int> > vert[MAX_N];
BIT<long long, MX> b1;
BIT<long long, MX> b2;
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> numH >> numV;
  for (int i = 0; i < numH; i++) {
    cin >> horiz[i].first >> horiz[i].second.first >> horiz[i].second.second;
  }
  for (int i = 0; i < numV; i++) {
    cin >> vert[i].first >> vert[i].second.first >> vert[i].second.second;
  }
  vector<pair<int, int> > horizFromLeft;
  vector<pair<int, int> > horizFromRight;
  for (int i = 0; i < numH; i++) {
    if (horiz[i].second.first == 0)
      horizFromLeft.push_back(
          make_pair(horiz[i].first, horiz[i].second.second));
    else
      horizFromRight.push_back(
          make_pair(horiz[i].first, horiz[i].second.first));
  }
  sort(horizFromLeft.begin(), horizFromLeft.end(),
       [&](const pair<int, int>& p1, const pair<int, int>& p2) {
         return p1.second < p2.second;
       });
  sort(vert, vert + numV);
  int idx = -1;
  long long ans = 1;
  for (int i = 0; i < numH; i++)
    if (horiz[i].second.first == 0 && horiz[i].second.second == 1000000) ans++;
  for (int i = 0; i < numV; i++)
    if (vert[i].second.first == 0 && vert[i].second.second == 1000000) ans++;
  for (pair<int, int> p : horizFromLeft) {
    while (idx + 1 < numV && vert[idx + 1].first <= p.second) {
      idx++;
      b1.upd(vert[idx].second.first, vert[idx].second.second, 1);
    }
    ans += b1.query(p.first);
  }
  sort(horizFromRight.begin(), horizFromRight.end(),
       [&](const pair<int, int>& p1, const pair<int, int>& p2) {
         return p1.second > p2.second;
       });
  idx = numV;
  for (pair<int, int> p : horizFromRight) {
    while (idx - 1 >= 0 && vert[idx - 1].first >= p.second) {
      idx--;
      b2.upd(vert[idx].second.first, vert[idx].second.second, 1);
    }
    ans += b2.query(p.first);
  }
  return cout << ans << '\n', 0;
  ;
}
