#include <bits/stdc++.h>
using i32 = std::int_least32_t;
using i64 = std::int_least64_t;
using u32 = std::uint_least32_t;
using u64 = std::uint_least64_t;
using usize = std::size_t;
template <class T>
using vec = std::vector<T>;
template <class T>
using numr = std::numeric_limits<T>;
int main() {
  std::cin.tie(nullptr);
  std::ios::sync_with_stdio(false);
  std::cout << std::setprecision(15) << std::fixed;
  i64 inf = numr<i64>::max();
  usize n, m;
  std::cin >> n >> m;
  vec<i64> X = {-inf, inf};
  vec<i64> Y = {-inf, inf};
  vec<std::tuple<i64, i64, i64>> ver(n);
  vec<std::tuple<i64, i64, i64>> hor(m);
  for (usize i = 0; i < n; i++) {
    i64 a, b, c;
    std::cin >> a >> b >> c;
    X.push_back(a);
    X.push_back(b);
    Y.push_back(c);
    ver.at(i) = {a, b, c};
  }
  for (usize i = 0; i < m; i++) {
    i64 a, b, c;
    std::cin >> a >> b >> c;
    X.push_back(a);
    Y.push_back(b);
    Y.push_back(c);
    hor.at(i) = {a, b, c};
  }
  std::sort(std::begin(X), std::end(X));
  X.resize(std::unique(std::begin(X), std::end(X)) - X.begin());
  std::sort(std::begin(Y), std::end(Y));
  Y.resize(std::unique(std::begin(Y), std::end(Y)) - Y.begin());
  auto x_rev = [&](i64 x) {
    auto lb = std::lower_bound(std::begin(X), std::end(X), x);
    assert(lb != X.end() && *lb == x);
    return lb - X.begin();
  };
  auto y_rev = [&](i64 x) {
    auto lb = std::lower_bound(std::begin(Y), std::end(Y), x);
    assert(lb != Y.end() && *lb == x);
    return lb - Y.begin();
  };
  for (auto&& [a, b, c] : ver) {
    a = x_rev(a);
    b = x_rev(b);
    c = y_rev(c);
  }
  for (auto&& [a, b, c] : hor) {
    a = x_rev(a);
    b = y_rev(b);
    c = y_rev(c);
  }
  (void)0;
  (void)0;
  auto return_if_inf = [&](i64 i, i64 j) {
    (void)0;
    if (i == 0 || j == 0 || i == (i64)X.size() - 2 || j == (i64)Y.size() - 2) {
      std::cout << "INF" << '\n';
      exit(0);
    }
  };
  auto area = [&](i64 i, i64 j) {
    return (X.at(i + 1) - X.at(i)) * (Y.at(j + 1) - Y.at(j));
  };
  (void)0;
  vec<vec<vec<i64>>> g(X.size(), vec<vec<i64>>(Y.size(), vec<i64>(4)));
  for (auto&& [l, r, j] : ver) {
    assert(1 <= j);
    for (i64 i = l; i < r; i++) {
      g.at(i).at(j - 1).at(2) = true;
      g.at(i).at(j).at(3) = true;
    }
  }
  for (auto&& [i, l, r] : hor) {
    assert(1 <= i);
    for (i64 j = l; j < r; j++) {
      g.at(i - 1).at(j).at(0) = true;
      g.at(i).at(j).at(1) = true;
    }
  }
  vec<std::pair<i64, i64>> didj = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
  i64 sx = std::lower_bound(std::begin(X), std::end(X), 0) - X.begin();
  i64 sy = std::lower_bound(std::begin(X), std::end(X), 0) - X.begin();
  (void)0;
  vec<vec<i64>> ckd(X.size(), vec<i64>(Y.size()));
  ckd.at(sx).at(sy) = true;
  vec<std::pair<i64, i64>> que = {{sx, sy}};
  i64 ans = 0;
  for (usize t = 0; t < que.size(); t++) {
    auto [i, j] = que.at(t);
    return_if_inf(i, j);
    ans += area(i, j);
    (void)0;
    for (usize k = 0; k < 4; k++)
      if (!g.at(i).at(j).at(k)) {
        auto [di, dj] = didj.at(k);
        i64 ni = i + di;
        i64 nj = j + dj;
        if (ckd.at(ni).at(nj)) continue;
        ckd.at(ni).at(nj) = true;
        que.emplace_back(ni, nj);
      }
  }
  std::cout << ans << '\n';
}
