#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1e9 + 7;
const int INF = 1e9;
const long long IINF = 1e18;
const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
const char dir[4] = {'D', 'R', 'U', 'L'};
template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
  for (T &x : v) is >> x;
  return is;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (int i = 0; i < v.size(); ++i) {
    os << v[i] << (i + 1 == v.size() ? "" : " ");
  }
  return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  cout << '(' << p.first << ',' << p.second << ')';
  return os;
}
void debug_out() { cerr << '\n'; }
template <class Head, class... Tail>
void debug_out(Head &&head, Tail &&...tail) {
  cerr << head;
  if (sizeof...(Tail) > 0) cerr << ", ";
  debug_out(move(tail)...);
}
template <class T1, class T2>
inline bool chmin(T1 &a, T2 b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T1, class T2>
inline bool chmax(T1 &a, T2 b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
struct UnionFind {
  int num;
  vector<int> par, rank;
  UnionFind(int n) : num(n), par(n), rank(n, 1) {
    iota(par.begin(), par.end(), 0);
  }
  int root(int x) {
    if (par[x] == x) return x;
    return par[x] = root(par[x]);
  }
  bool merge(int x, int y) {
    x = root(x), y = root(y);
    if (x == y) return false;
    if (rank[x] < rank[y]) swap(x, y);
    par[y] = x;
    rank[x] += rank[y];
    --num;
    return true;
  }
  bool same(int x, int y) { return root(x) == root(y); }
  int size(int x) { return rank[root(x)]; }
  int count() { return num; }
};
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int N, M;
  cin >> N >> M;
  vector<long long> A(N), B(N), C(N), D(M), E(M), F(M), xs, ys;
  for (int i = 0; i < N; ++i) {
    cin >> A[i] >> B[i] >> C[i];
    xs.emplace_back(A[i]);
    xs.emplace_back(B[i]);
    ys.emplace_back(C[i]);
  }
  for (int i = 0; i < M; ++i) {
    cin >> D[i] >> E[i] >> F[i];
    xs.emplace_back(D[i]);
    ys.emplace_back(E[i]);
    ys.emplace_back(F[i]);
  }
  sort(xs.begin(), xs.end());
  sort(ys.begin(), ys.end());
  xs.erase(unique(xs.begin(), xs.end()), xs.end());
  ys.erase(unique(ys.begin(), ys.end()), ys.end());
  for (int i = 0; i < N; ++i) {
    A[i] = lower_bound(xs.begin(), xs.end(), A[i]) - xs.begin();
    B[i] = lower_bound(xs.begin(), xs.end(), B[i]) - xs.begin();
    C[i] = lower_bound(ys.begin(), ys.end(), C[i]) - ys.begin();
  }
  for (int i = 0; i < M; ++i) {
    D[i] = lower_bound(xs.begin(), xs.end(), D[i]) - xs.begin();
    E[i] = lower_bound(ys.begin(), ys.end(), E[i]) - ys.begin();
    F[i] = lower_bound(ys.begin(), ys.end(), F[i]) - ys.begin();
  }
  int X = xs.size() - 1, Y = ys.size() - 1;
  int sx = lower_bound(xs.begin(), xs.end(), 0) - xs.begin() - 1;
  int sy = lower_bound(ys.begin(), ys.end(), 0) - ys.begin() - 1;
  if (sx < 0 || sy < 0) {
    cout << "INF" << '\n';
    return 0;
  }
  int s = sx * Y + sy;
  vector<vector<bool>> wy(Y + 1, vector<bool>(X)), wx(X + 1, vector<bool>(Y));
  for (int i = 0; i < N; ++i) {
    for (int j = A[i]; j < B[i]; ++j) {
      wy[C[i]][j] = true;
    }
  }
  for (int i = 0; i < M; ++i) {
    for (int j = E[i]; j < F[i]; ++j) {
      wx[D[i]][j] = true;
    }
  }
  UnionFind uf(X * Y + 1);
  for (int i = 0; i <= Y; ++i) {
    for (int j = 0; j < X; ++j) {
      if (!wy[i][j]) {
        if (i == 0)
          uf.merge(j * Y + i, X * Y);
        else if (i == Y)
          uf.merge(j * Y + i - 1, X * Y);
        else
          uf.merge(j * Y + i - 1, j * Y + i);
      }
    }
  }
  for (int i = 0; i <= X; ++i) {
    for (int j = 0; j < Y; ++j) {
      if (!wx[i][j]) {
        if (i == 0)
          uf.merge(i * X + j, X * Y);
        else if (i == X)
          uf.merge((i - 1) * X + j, X * Y);
        else
          uf.merge((i - 1) * X + j, i * X + j);
      }
    }
  }
  if (uf.same(s, X * Y)) {
    cout << "INF" << '\n';
    return 0;
  }
  long long ans = 0;
  for (int i = 0; i < X * Y; ++i)
    if (uf.same(s, i)) {
      ans += (xs[i / Y + 1] - xs[i / Y]) * (ys[i % Y + 1] - ys[i % Y]);
    }
  cout << ans << '\n';
}
