#include<iostream>
#include<queue>
#include<map>
#include<algorithm>
#include<cstdint>
#include<cstdlib>
template<typename T>
void fin(T const& t){ std::cout << t << std::endl; exit(0); }

struct line { int64_t p, q, r; line(){} };
void su(std::vector<int>& v) {
  std::sort(v.begin(), v.end());
  v.erase(std::unique(v.begin(),v.end()), v.end());
}

int main() {
  int N, M; std::cin >> N >> M;
  std::vector<int> xs(M), ys(N);
  std::vector<line> hL(N), vL(M);
  // (p...q, r) / (p, q...r)
  for(int i = 0; i < N; ++i) { std::cin >> hL[i].p >> hL[i].q >> hL[i].r; ys[i]=hL[i].r; }
  for(int i = 0; i < M; ++i) { std::cin >> vL[i].p >> vL[i].q >> vL[i].r; xs[i]=vL[i].p; }
  su(xs); su(ys);
  if(xs[0] >= 0 || xs.back() <= 0 || ys[0] >= 0 || ys.back() <= 0) fin("INF");
  
  // walls
  int XS = xs.size(), YS = ys.size();
  std::vector<std::vector<int>> hW(YS, std::vector<int>(XS, 0)), vW(YS, std::vector<int>(YS, 0));
  for(auto const& w: hL) { // w.p < w.q : given
    int x1 = std::max(0, (int)(std::lower_bound(xs.begin(), xs.end(), w.p) - xs.begin()));
    int x2 = std::min(XS, (int)(std::upper_bound(xs.begin(), xs.end(), w.q) - xs.begin()))-1;
    if(x2 <= 0 || x1 >= XS-1) continue;
    int y  = std::lower_bound(ys.begin(), ys.end(), w.r) - ys.begin();
    assert(0 <= y && y <= YS-1);
    assert(0 <= x1 && x1 <= XS-2);
    assert(1 <= x2 && x2 <= XS-1);
    ++hW[y][x1];
    --hW[y][x2];
  }
  for(auto const& w: vL) { // w.q < w.r : given
    int x  = std::lower_bound(xs.begin(), xs.end(), w.p) - xs.begin();
    int y1 = std::max(0, (int)(std::lower_bound(ys.begin(), ys.end(), w.q) - ys.begin()));
    int y2 = std::min(YS, (int)(std::upper_bound(ys.begin(), ys.end(), w.r) - ys.begin()))-1;
    if(y2 <= 0 || y1 >= YS-1) continue;
    assert(0 <= x && x <= XS-1);
    assert(0 <= y1 && y1 <= YS-2);
    assert(1 <= y2 && y2 <= YS-1);
    ++vW[y1][x];
    --vW[y2][x];
  }
  for(int y = 0; y < YS; ++y) for(int x = 1; x < XS; ++x) hW[y][x] += hW[y][x-1];
  for(int x = 0; x < XS; ++x) for(int y = 1; y < YS; ++y) vW[y][x] += vW[y-1][x];
  // bfs
  std::vector<std::vector<bool>> visited(YS-1, std::vector<bool>(XS-1, false));
  std::queue<std::pair<int,int>> q;
  int x = std::lower_bound(xs.begin(), xs.end(), 0) - xs.begin() - 1;
  int y = std::lower_bound(ys.begin(), ys.end(), 0) - ys.begin() - 1;
  q.push(std::make_pair(x, y));
  while(!q.empty()) {
    auto const& p = q.front(); x = p.first; y = p.second; q.pop();
    if(visited[y][x]) continue;
    visited[y][x] = true;
    // ydec
    if(hW[y][x] < 1) {
      if(y <= 0) fin("INF");
      if(!visited[y-1][x]) q.push(std::make_pair(x, y-1));
    }
    // yinc
    if(hW[y+1][x] < 1) {
      if(y >= YS-2) fin("INF");
      if(!visited[y+1][x]) q.push(std::make_pair(x, y+1));
    }
    // xdec
    if(vW[y][x] < 1) {
      if(x <= 0) fin("INF");
      if(!visited[y][x-1]) q.push(std::make_pair(x-1, y));
    }
    // xinc
    if(vW[y][x+1] < 1) {
      if(x >= XS-2) fin("INF");
      if(!visited[y][x+1]) q.push(std::make_pair(x+1, y));
    }
  }
  // calc area
  int64_t ans = 0;
  for(int y = 0; y < YS-1; ++y) for(int x = 0; x < XS-1; ++x) if(visited[y][x]) {
    ans += (int64_t)(xs[x+1] - xs[x])*(ys[y+1] - ys[y]);
  }
  fin(ans);
  return 0;
}
