#line 1 "F.cpp"
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <complex>
#include <map>
#include <queue>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

#line 1 "~/git/library/utility/four_neighbor.cpp"



/**
 * @brief 4-近傍
 * @author えびちゃん
 */

#include <cstddef>
#include <array>

#line 1 "~/git/library/utility/literals.cpp"



/**
 * @brief ユーザ定義リテラル
 * @author えびちゃん
 */

#line 11 "~/git/library/utility/literals.cpp"

constexpr intmax_t  operator ""_jd(unsigned long long n) { return n; }
constexpr uintmax_t operator ""_ju(unsigned long long n) { return n; }
constexpr size_t    operator ""_zu(unsigned long long n) { return n; }
constexpr ptrdiff_t operator ""_td(unsigned long long n) { return n; }


#line 13 "~/git/library/utility/four_neighbor.cpp"

constexpr std::array<size_t, 4> di{{-1_zu, 0, 1, 0}};
constexpr std::array<size_t, 4> dj{{0, -1_zu, 0, 1}};


#line 1 "~/git/library/utility/make/vector.cpp"
/**
 * @brief 多次元 vector の作成
 * @author えびちゃん
 */

#ifndef H_make_vector
#define H_make_vector

#line 10 "~/git/library/utility/make/vector.cpp"
#include <type_traits>
#line 12 "~/git/library/utility/make/vector.cpp"

namespace detail {
  template <typename Tp, size_t Nb>
  auto make_vector(std::vector<size_t>& sizes, Tp const& x) {
    if constexpr (Nb == 1) {
      return std::vector(sizes[0], x);
    } else {
      size_t size = sizes[Nb-1];
      sizes.pop_back();
      return std::vector(size, make_vector<Tp, Nb-1>(sizes, x));
    }
  }
}  // detail::

template <typename Tp, size_t Nb>
auto make_vector(size_t const(&sizes)[Nb], Tp const& x = Tp()) {
  std::vector<size_t> s(Nb);
  for (size_t i = 0; i < Nb; ++i) s[i] = sizes[Nb-i-1];
  return detail::make_vector<Tp, Nb>(s, x);
}

#endif  /* !defined(H_make_vector) */
#line 15 "F.cpp"

int main() {
  size_t n, m;
  scanf("%zu %zu", &n, &m);

  std::map<intmax_t, size_t> xe, ye;
  std::vector<std::tuple<intmax_t, intmax_t, intmax_t>> xl(n), yl(m);
  for (size_t i = 0; i < n; ++i) {
    intmax_t a, b, c;
    scanf("%jd %jd %jd", &a, &b, &c);
    xe[a], xe[b], ye[c];
    xl[i] = {a, b, c};
  }

  for (size_t j = 0; j < m; ++j) {
    intmax_t d, e, f;
    scanf("%jd %jd %jd", &d, &e, &f);
    xe[d], ye[e], ye[f];
    yl[j] = {d, e, f};
  }

  intmax_t const inf = 2e9;

  xe[0], ye[0];
  xe[inf], ye[inf];

  size_t mx = 0, my = 0;
  std::vector<intmax_t> xd, yd;
  for (auto& [d, e]: xe) xd.push_back(d), e = mx++;
  for (auto& [d, e]: ye) yd.push_back(d), e = my++;

  auto pl = make_vector({2*mx+2, 2*my+2}, 0);
  for (auto [a, b, c]: xl) {
    size_t il = 2 * xe.at(a);
    size_t ir = 2 * xe.at(b) + 1;
    size_t j = 2 * ye.at(c);
    ++pl[il][j];
    --pl[ir][j];
    --pl[il][j+1];
    ++pl[ir][j+1];
  }

  for (auto [d, e, f]: yl) {
    size_t i = 2 * xe.at(d);
    size_t jl = 2 * ye.at(e);
    size_t jr = 2 * ye.at(f) + 1;
    ++pl[i][jl];
    --pl[i][jr];
    --pl[i+1][jl];
    ++pl[i+1][jr];
  }

  for (size_t i = 0; i < pl.size(); ++i)
    for (size_t j = 1; j < pl[i].size(); ++j)
      pl[i][j] += pl[i][j-1];

  for (size_t i = 1; i < pl.size(); ++i)
    for (size_t j = 0; j < pl[i].size(); ++j)
      pl[i][j] += pl[i-1][j];

  std::vector<std::string> s(pl.size(), std::string(pl[0].size(), '.'));
  for (size_t i = 0; i < pl.size(); ++i)
    for (size_t j = 0; j < pl[0].size(); ++j)
      if (pl[i][j] != 0) s[i][j] = '#';

  // for (auto const& si: s) fprintf(stderr, "%s\n", si.data());

  size_t si = 2 * xe.at(0);
  size_t sj = 2 * ye.at(0);
  size_t gi = 2 * xe.at(inf);
  size_t gj = 2 * ye.at(inf);

  std::queue<std::pair<size_t, size_t>> q;
  q.emplace(si, sj);
  auto vis = make_vector({s.size(), s[0].length()}, false);
  vis[si][sj] = true;
  while (!q.empty()) {
    auto [i, j] = q.front();
    q.pop();
    for (size_t k = 0; k < 4; ++k) {
      size_t ni = i + di[k];
      size_t nj = j + dj[k];
      if (!(ni < s.size() && nj < s[0].length())) continue;
      if (s[ni][nj] == '#') continue;
      if (vis[ni][nj]) continue;
      vis[ni][nj] = true;
      q.emplace(ni, nj);
    }
  }

  if (vis[gi][gj]) return puts("INF"), 0;

  // for (size_t i = 0; i < s.size(); ++i)
  //   for (size_t j = 0; j < s[i].length(); ++j)
  //     fprintf(stderr, "%zu%c", ds.representative(enc(i, j)), j+1<s[i].length()? ' ': '\n');

  intmax_t res = 0;
  for (size_t i = 0; i < s.size(); ++i)
    for (size_t j = 0; j < s[i].length(); ++j) {
      if (s[i][j] == '#') continue;
      if (!vis[i][j]) continue;
      if (!(i % 2 == 1 && j % 2 == 1)) continue;
      // fprintf(stderr, "(%zu, %zu)\n", i, j);
      intmax_t y = yd[j/2+1] - yd[j/2];
      intmax_t x = xd[i/2+1] - xd[i/2];
      res += x * y;
    }

  printf("%jd\n", res);
}
