#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
template <typename T1, typename T2>
inline void chkmin(T1 &x, const T2 &y) {
  if (x > y) x = y;
}
template <typename T1, typename T2>
inline void chkmax(T1 &x, const T2 &y) {
  if (x < y) x = y;
}
struct segm {
  int l, r;
  segm() {}
  segm(int _l, int _r) { l = _l, r = _r; }
};
bool operator<(const segm &a, const segm &b) { return a.l < b.l; }
void Unique(vector<segm> &a) {
  vector<segm> ans;
  sort(a.begin(), a.end());
  for (auto [l, r] : a) {
    if (ans.empty() || ans.back().r < l) {
      ans.push_back({l, r});
    } else {
      chkmax(ans[ans.size() - 1].r, r);
    }
  }
  a = ans;
}
int n, m;
map<int, vector<segm>> a[2];
void read() {
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    int x, l, r;
    cin >> l >> r >> x;
    a[0][x].push_back({l, r});
  }
  for (int i = 0; i < m; i++) {
    int x, l, r;
    cin >> x >> l >> r;
    a[1][x].push_back({l, r});
  }
  for (int ind = 0; ind < 2; ind++) {
    for (auto &i : a[ind]) {
      Unique(i.second);
    }
  }
}
vector<int> coord[2];
bool check(int ind, int x, int start) {
  int L = coord[ind ^ 1][start];
  int R = coord[ind ^ 1][start + 1];
  x = coord[ind][x];
  auto it = upper_bound(a[ind][x].begin(), a[ind][x].end(), segm(L, R));
  if (it == a[ind][x].begin()) return true;
  it--;
  if (it->r >= R) return false;
  return true;
}
void INF() {
  cout << "INF\n";
  exit(0);
}
ll ans;
vector<vector<bool>> used;
void add(int x, int y) {
  ans += (ll)(coord[0][x + 1] - coord[0][x]) * (coord[1][y + 1] - coord[1][y]);
}
vector<int> dx = {-1, 0, 1, 0};
vector<int> dy = {0, 1, 0, -1};
vector<int> dind = {0, 1, 0, 1};
vector<int> delta = {0, 1, 1, 0};
bool check(int x, int y) {
  return x >= 0 && x < coord[0].size() - 1 && y >= 0 && y < coord[1].size() - 1;
}
void run() {
  for (int ind = 0; ind < 2; ind++) {
    for (auto i : a[ind]) {
      coord[ind].push_back(i.first);
      for (auto [l, r] : i.second) {
        coord[ind ^ 1].push_back(l);
        coord[ind ^ 1].push_back(r);
      }
    }
  }
  for (int ind = 0; ind < 2; ind++) {
    sort(coord[ind].begin(), coord[ind].end());
    coord[ind].resize(unique(coord[ind].begin(), coord[ind].end()) -
                      coord[ind].begin());
    if (coord[ind].empty()) INF();
    if (coord[ind][0] >= 0) INF();
    if (coord[ind].back() <= 0) INF();
  }
  used.resize(coord[0].size() - 1, vector<bool>(coord[1].size() - 1, false));
  queue<pair<int, int>> q;
  ans = 0;
  for (int i = 0; i < coord[0].size() - 1; i++) {
    for (int j = 0; j < coord[1].size() - 1; j++) {
      if (q.empty() && coord[0][i] <= 0 && coord[0][i + 1] >= 0 &&
          coord[1][j] <= 0 && coord[1][j + 1] >= 0) {
        q.push({i, j});
        used[i][j] = true;
      }
    }
  }
  while (!q.empty()) {
    auto v = q.front();
    add(v.first, v.second);
    q.pop();
    for (int it = 0; it < 4; it++) {
      int nx = v.first + dx[it];
      int ny = v.second + dy[it];
      bool go =
          check(dind[it], delta[it] + (dind[it] == 0 ? v.first : v.second),
                dind[it] == 0 ? v.second : v.first);
      if (!go) continue;
      if (!check(nx, ny)) INF();
      if (used[nx][ny]) continue;
      used[nx][ny] = true;
      q.push({nx, ny});
    }
  }
}
void write() { cout << ans << endl; }
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  read();
  run();
  write();
  return 0;
}
