#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr ll INF = (ll)1e18;
constexpr ll MOD = (ll)1e9 + 7;
constexpr double EPS = 1e-9;
constexpr ll dx[4] = {1, 0, -1, 0};
constexpr ll dy[4] = {0, 1, 0, -1};
constexpr ll dx8[8] = {1, 0, -1, 0, 1, 1, -1, -1};
constexpr ll dy8[8] = {0, 1, 0, -1, 1, -1, 1, -1};
void p() { std::cout << '\n'; }
template <typename Head, typename... Tail>
void p(Head head, Tail... tail) {
  std::cout << head << (sizeof...(tail) ? " " : "");
  p(tail...);
}
template <typename T>
inline void pv(std::vector<T>& v) {
  for (ll i = 0, N = v.size(); i < N; i++)
    std::cout << v[i] << " \n"[i == N - 1];
}
template <typename T>
inline bool chmax(T& a, T b) {
  return a < b && (a = b, true);
}
template <typename T>
inline bool chmin(T& a, T b) {
  return a > b && (a = b, true);
}
template <typename T>
inline void uniq(std::vector<T>& v) {
  v.erase(std::unique(v.begin(), v.end()), v.end());
}
class UnionFind {
 public:
  vector<ll> v;
  UnionFind(size_t size) : v(size, -1) {}
  ll root(ll x) { return (v[x] < 0 ? x : v[x] = root(v[x])); }
  bool is_root(ll x) { return x == root(x); }
  bool is_same(ll x, ll y) { return root(x) == root(y); }
  bool unite(ll x, ll y) {
    x = root(x);
    y = root(y);
    if (x == y) return false;
    if (v[x] > v[y]) swap(x, y);
    v[x] += v[y];
    v[y] = x;
    return true;
  }
  ll size(ll x) { return -v[root(x)]; }
};
template <typename T>
class Compress {
 public:
  vector<T> xs;
  Compress() = default;
  Compress(const vector<T>& vs) { add(vs); }
  Compress(const initializer_list<vector<T>>& vs) {
    for (auto& p : vs) add(p);
  }
  void add(const vector<T>& vs) { copy(begin(vs), end(vs), back_inserter(xs)); }
  void add(const T& x) { xs.emplace_back(x); }
  void build() {
    sort(begin(xs), end(xs));
    xs.erase(unique(begin(xs), end(xs)), end(xs));
  }
  vector<ll> get(const vector<T>& vs) const {
    vector<ll> ret;
    transform(begin(vs), end(vs), back_inserter(ret), [&](const T& x) {
      return lower_bound(begin(xs), end(xs), x) - begin(xs);
    });
    return ret;
  }
  ll get(const T& x) const {
    return lower_bound(begin(xs), end(xs), x) - begin(xs);
  }
  const T& operator[](ll k) const { return xs[k]; }
  size_t size() const { return xs.size(); }
};
void solve() {
  ll N, M;
  cin >> N >> M;
  vector<ll> A(N), B(N), C(N);
  vector<ll> D(M), E(M), F(M);
  for (ll i = 0, i_length = (N); i < i_length; ++i) cin >> A[i] >> B[i] >> C[i];
  for (ll i = 0, i_length = (M); i < i_length; ++i) cin >> D[i] >> E[i] >> F[i];
  vector<ll> X, Y;
  X.push_back(-INF);
  X.push_back(INF);
  Y.push_back(-INF);
  Y.push_back(INF);
  for (ll i = 0, i_length = (N); i < i_length; ++i) {
    X.push_back(A[i]);
    X.push_back(B[i]);
    Y.push_back(C[i]);
  }
  for (ll i = 0, i_length = (M); i < i_length; ++i) {
    X.push_back(D[i]);
    Y.push_back(E[i]);
    Y.push_back(F[i]);
  }
  Compress<ll> compX(X), compY(Y);
  compX.build();
  compY.build();
  auto findx = [&](ll x) -> ll { return compX.get(x) - 1; };
  auto findy = [&](ll y) -> ll { return compY.get(y) - 1; };
  ll size = (compX.size() - 1) * (compY.size() - 1);
  vector<vector<bool>> up(compX.size() - 1,
                          vector<bool>(compY.size() - 1, false));
  vector<vector<bool>> left(compX.size() - 1,
                            vector<bool>(compY.size() - 1, false));
  do {
  } while (false);
  do {
  } while (false);
  for (ll i = 0, i_length = (N); i < i_length; ++i) {
    ll a = compX.get(A[i]);
    ll b = compX.get(B[i]);
    ll c = compY.get(C[i]);
    do {
    } while (false);
    for (ll x = a; x < b; x++) {
      left[x][c] = true;
    }
  }
  for (ll i = 0, i_length = (M); i < i_length; ++i) {
    ll d = compX.get(D[i]);
    ll e = compX.get(E[i]);
    ll f = compY.get(F[i]);
    for (ll y = e; y < f; y++) {
      up[d][y] = true;
    }
  }
  do {
  } while (false);
  do {
  } while (false);
  auto encode = [&](ll x, ll y) { return x * (compY.size() - 1) + y; };
  UnionFind uf(size);
  for (ll i = 0; i < (ll)compX.size() - 1; i++)
    for (ll j = 0; j < (ll)compY.size() - 1; j++) {
      if (i > 0 && !up[i][j]) uf.unite(encode(i, j), encode(i - 1, j));
      if (j > 0 && !left[i][j]) uf.unite(encode(i, j), encode(i, j - 1));
    }
  do {
  } while (false);
  ll x0 = findx(0);
  ll y0 = findy(0);
  for (ll i = 0, i_length = (compX.size() - 1); i < i_length; ++i) {
    if (uf.is_same(encode(x0, y0), encode(i, 0)) ||
        uf.is_same(encode(x0, y0), encode(i, compY.size() - 2))) {
      p("INF");
      return;
    }
  }
  for (ll j = 0, j_length = (compY.size() - 1); j < j_length; ++j) {
    if (uf.is_same(encode(x0, y0), encode(0, j)) ||
        uf.is_same(encode(x0, y0), encode(compX.size() - 2, j))) {
      p("INF");
      return;
    }
  }
  auto lenx = [&](ll x) -> ll { return compX[x + 1] - compX[x]; };
  auto leny = [&](ll y) -> ll { return compY[y + 1] - compY[y]; };
  ll ans = 0;
  for (ll i = 0, i_length = (compX.size() - 1); i < i_length; ++i)
    for (ll j = 0, j_length = (compY.size() - 1); j < j_length; ++j) {
      if (uf.is_same(encode(x0, y0), encode(i, j))) {
        ans += lenx(i) * leny(j);
      }
    }
  p(ans);
}
signed main() {
  std::cin.tie(nullptr);
  std::ios::sync_with_stdio(false);
  solve();
  return 0;
}
