#include <bits/stdc++.h>
using lnt = long long;
constexpr lnt INF = 2e18;
struct UnionFind {
  int n;
  std::vector<int> par, size;
  UnionFind(int sz) : n(sz), par(sz, 0), size(sz, 1) {
    std::iota(par.begin(), par.end(), 0);
  }
  int find(int x) {
    if (par[x] == x) return x;
    return par[x] = find(par[x]);
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    if (size[x] < size[y]) std::swap(x, y);
    size[x] += size[y];
    par[y] = x;
  }
};
template <typename T = lnt>
struct CoordinateCompression {
  std::vector<T> r;
  CoordinateCompression() {}
  void build(bool sorted = false) {
    if (!sorted) std::sort(r.begin(), r.end());
    r.erase(std::unique(r.begin(), r.end()), r.end());
  }
  int operator[](const T& k) const {
    return (int)(std::lower_bound(r.begin(), r.end(), k) - r.begin());
  }
};
struct P {
  lnt a, b, c;
  P(lnt a, lnt b, lnt c) : a(a), b(b), c(c) {}
};
int main() {
  lnt n, m;
  std::cin >> n >> m;
  std::vector<std::vector<P>> edges(2);
  std::vector<CoordinateCompression<lnt>> C(2);
  for (int i = 0; i < (n); ++i) {
    lnt a, b, c;
    std::cin >> a >> b >> c;
    edges[0].emplace_back(a, b, c);
    C[0].r.emplace_back(a);
    C[0].r.emplace_back(b);
    C[1].r.emplace_back(c);
  }
  for (int i = 0; i < (m); ++i) {
    lnt a, b, c;
    std::cin >> c >> a >> b;
    edges[1].emplace_back(a, b, c);
    C[1].r.emplace_back(a);
    C[1].r.emplace_back(b);
    C[0].r.emplace_back(c);
  }
  C[0].r.emplace_back(0);
  C[1].r.emplace_back(0);
  for (int i = 0; i < (2); ++i) C[i].build();
  lnt N = C[0].r.size() + 1;
  lnt M = C[1].r.size() + 1;
  std::vector<std::vector<lnt>> bN(N, std::vector<lnt>(M, 0));
  std::vector<std::vector<lnt>> bM(M, std::vector<lnt>(N, 0));
  for (auto e : edges[0]) {
    bM[C[1][e.c]][C[0][e.a]]++;
    bM[C[1][e.c]][C[0][e.b]]--;
  }
  for (auto e : edges[1]) {
    bN[C[0][e.c]][C[1][e.a]]++;
    bN[C[0][e.c]][C[1][e.b]]--;
  }
  for (int i = 0; i < (N - 1); ++i) {
    for (int j = 0; j < (M - 1); ++j) {
      bN[i][j + 1] += bN[i][j];
      bM[j][i + 1] += bM[j][i];
    }
  }
  auto enc = [&](int i, int j) -> lnt { return i * M + j; };
  UnionFind uf(N * M);
  for (int i = 0; i < (N); ++i) {
    for (int j = 0; j < (M); ++j) {
      if (i == 0 || i == N - 1 || bM[j][i - 1] == 0) {
        uf.unite(enc(i, j), enc(i, j + 1));
      }
      if (j == 0 || j == M - 1 || bN[i][j - 1] == 0) {
        uf.unite(enc(i, j), enc(i + 1, j));
      }
    }
  }
  lnt sx = C[0][0] + 1;
  lnt sy = C[1][0] + 1;
  lnt root = uf.find(enc(sx, sy));
  lnt sum = 0;
  for (int i = 0; i < (N); ++i) {
    for (int j = 0; j < (M); ++j) {
      if (uf.find(enc(i, j)) == root) {
        if (i == 0 || j == 0 || i == N - 1 || j == M - 1) {
          std::cout << ("INF") << '\n';
          return 0;
        }
        sum += (C[0].r[i] - C[0].r[i - 1]) * (C[1].r[j] - C[1].r[j - 1]);
      }
    }
  }
  std::cout << (sum) << '\n';
}
