#include <bits/stdc++.h>
using namespace std;
const long long INF = 1001001001;
const long long LINF = 1001001001001001001;
const long long D4[] = {0, 1, 0, -1, 0};
const long long D8[] = {0, 1, 1, 0, -1, -1, 1, -1, 0};
template <class T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
using pq = priority_queue<T, vector<T>, greater<T>>;
long long N;
long long M;
vector<long long> A;
vector<long long> B;
vector<long long> C;
vector<long long> D;
vector<long long> E;
vector<long long> F;
void solve();
int main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cin >> N;
  cin >> M;
  A = vector<long long>(N);
  B = vector<long long>(N);
  C = vector<long long>(N);
  for (int i = 0; i < N; ++i) {
    cin >> A[i];
    cin >> B[i];
    cin >> C[i];
  }
  D = vector<long long>(M);
  E = vector<long long>(M);
  F = vector<long long>(M);
  for (int i = 0; i < M; ++i) {
    cin >> D[i];
    cin >> E[i];
    cin >> F[i];
  }
  solve();
}
struct UnionFind {
  vector<int> par;
  UnionFind(int sz) { par.assign(sz + 1, -1); }
  bool unite(int x, int y) {
    x = find(x), y = find(y);
    if (x == y) return false;
    if (par[x] > par[y]) swap(x, y);
    par[x] += par[y];
    par[y] = x;
    return true;
  }
  int find(int x) {
    if (par[x] < 0) return x;
    return par[x] = find(par[x]);
  }
  int size(int x) { return -par[find(x)]; }
};
void solve() {
  vector<long long> xd, yd;
  xd.push_back(-INF);
  xd.push_back(INF);
  yd.push_back(-INF);
  yd.push_back(INF);
  for (long long i = 0; i < (N); ++i) {
    xd.push_back(A[i]);
    xd.push_back(B[i]);
    yd.push_back(C[i]);
  }
  for (long long i = 0; i < (M); ++i) {
    xd.push_back(D[i]);
    yd.push_back(E[i]);
    yd.push_back(F[i]);
  }
  sort((xd).begin(), (xd).end());
  sort((yd).begin(), (yd).end());
  xd.erase(unique((xd).begin(), (xd).end()), xd.end());
  yd.erase(unique((yd).begin(), (yd).end()), yd.end());
  long long n = xd.size() - 1, m = yd.size() - 1;
  vector<vector<long long>> ok(4, vector<long long>(n * m, 1));
  for (long long i = 0; i < (N); ++i) {
    long long xidx = lower_bound((xd).begin(), (xd).end(), A[i]) - xd.begin();
    long long yidx = lower_bound((yd).begin(), (yd).end(), C[i]) - yd.begin();
    for (long long j = xidx; xd[j] < B[i]; ++j) {
      ok[2][j * m + yidx] = 0;
      ok[0][j * m + yidx - 1] = 0;
    }
  }
  for (long long i = 0; i < (M); ++i) {
    long long xidx = lower_bound((xd).begin(), (xd).end(), D[i]) - xd.begin();
    long long yidx = lower_bound((yd).begin(), (yd).end(), E[i]) - yd.begin();
    for (long long j = yidx; yd[j] < F[i]; ++j) {
      ok[3][xidx * m + j] = 0;
      ok[1][(xidx - 1) * m + j] = 0;
    }
  }
  UnionFind uf(n * m);
  for (long long i = 0; i < (n * m); ++i) {
    long long tx = i / m, ty = i % m;
    for (long long j = 0; j < (4); ++j) {
      long long nx = tx + D4[j], ny = ty + D4[j + 1];
      if (!ok[j][i] || nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
      uf.unite(tx * m + ty, nx * m + ny);
    }
  }
  long long sx = lower_bound((xd).begin(), (xd).end(), 0) - xd.begin();
  long long sy = lower_bound((yd).begin(), (yd).end(), 0) - yd.begin();
  long long ans = 0;
  for (long long i = 0; i < (n); ++i)
    for (long long j = 0; j < (m); ++j) {
      if (uf.find(i * m + j) == uf.find(sx * m + sy)) {
        if (i == 0 || i == n - 1 || j == 0 || j == m - 1) {
          cout << "INF" << endl;
          return;
        }
        ans += (xd[i + 1] - xd[i]) * (yd[i + 1] - yd[i]);
      }
    }
  assert(false);
  cout << ans << endl;
}
