#include <bits/stdc++.h>
using namespace std;
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << "(" << p.first << "," << p.second << ")";
  return os;
}
#ifdef __LOCAL
#define debug(x) cerr << __LINE__ << ": " << #x << " = " << x << endl
#define debugArray(x, n)                           \
  cerr << __LINE__ << ": " << #x << " = {";        \
  for (long long hoge = 0; (hoge) < (n); ++(hoge)) \
    cerr << ((hoge) ? "," : "") << x[hoge];        \
  cerr << "}" << endl
#else
#define debug(x) (void(0))
#define debugArray(x, n) (void(0))
#endif

const int MAX_NN = 1000 * 1000 * 100;
int near[MAX_NN][4];
bool used[MAX_NN];
signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int N, M;
  cin >> N >> M;
  vector<long long> xs;
  xs.push_back(0);
  xs.push_back(-1e9 - 10);
  xs.push_back(1e9 + 10);
  vector<long long> ys;
  ys.push_back(0);
  ys.push_back(-1e9 - 10);
  ys.push_back(1e9 + 10);
  int A[N], B[N], C[N];
  for (int i = 0; i < N; i++) {
    cin >> A[i] >> B[i] >> C[i];
    xs.push_back(A[i] - 1);
    xs.push_back(A[i]);
    xs.push_back(B[i] - 1);
    xs.push_back(B[i]);
    ys.push_back(C[i] - 1);
    ys.push_back(C[i]);
  }
  int D[M], E[M], F[M];
  for (int i = 0; i < M; i++) {
    cin >> D[i] >> E[i] >> F[i];
    xs.push_back(D[i] - 1);
    xs.push_back(D[i]);
    ys.push_back(E[i] - 1);
    ys.push_back(E[i]);
    ys.push_back(F[i] - 1);
    ys.push_back(F[i]);
  }
  sort(xs.begin(), xs.end());
  xs.erase(unique(xs.begin(), xs.end()), xs.end());
  sort(ys.begin(), ys.end());
  ys.erase(unique(ys.begin(), ys.end()), ys.end());
  auto xi = [&](long long X) {
    return lower_bound(xs.begin(), xs.end(), X) - xs.begin();
  };
  auto yi = [&](long long Y) {
    return lower_bound(ys.begin(), ys.end(), Y) - ys.begin();
  };
  auto node = [&](int x, int y) { return x * ys.size() + y; };
  auto get_xy = [&](int v) { return make_pair(v / ys.size(), v % ys.size()); };
  int NN = xs.size() * ys.size();
  debug(NN);
  for (int i = 0; i < NN; i++) {
    int x, y;
    tie(x, y) = get_xy(i);
    near[i][0] = x > 0 ? node(x - 1, y) : -1;
    near[i][1] = y > 0 ? node(x, y - 1) : -1;
    near[i][2] = x + 1 < xs.size() ? node(x + 1, y) : -1;
    near[i][3] = y + 1 < ys.size() ? node(x, y + 1) : -1;
  }
  for (int i = 0; i < N; i++) {
    int y = yi(C[i]);
    for (int x = xi(A[i]); x < xi(B[i]); x++) {
      near[node(x, y)][1] = -1;
      if (y > 0) near[node(x, y - 1)][3] = -1;
    }
  }
  for (int i = 0; i < M; i++) {
    int x = xi(D[i]);
    for (int y = yi(E[i]); y < yi(F[i]); y++) {
      near[node(x, y)][0] = -1;
      if (x > 0) near[node(x - 1, y)][2] = -1;
    }
  }
  fill(used, used + NN, false);
  long long ans = 0;
  queue<int> que;
  que.push(node(xi(0), yi(0)));
  while (!que.empty()) {
    int v = que.front();
    que.pop();
    if (used[v]) continue;
    used[v] = true;
    int x, y;
    tie(x, y) = get_xy(v);
    if (x == 0 || x == xs.size() || y == 0 || y == ys.size()) {
      ans = -1;
      break;
    }
    ans += (xs[x + 1] - xs[x]) * (ys[y + 1] - ys[y]);
    for (int i = 0; i < 4; i++) {
      int u = near[v][i];
      if (u == -1 || used[u]) continue;
      que.push(u);
    }
  }
  if (ans == -1)
    cout << "INF" << endl;
  else
    cout << ans << endl;
  return 0;
}


Measured memory_bytes: 601924