#include <bits/stdc++.h>
using namespace std;
void debugF(ostream &os) { os << endl; }
template <typename Head, typename... Tail>
void debugF(ostream &os, Head H, Tail... T) {
  os << " " << H;
  debugF(os, T...);
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
  for (auto &x : v) is >> x;
  return is;
}
template <typename T>
ostream &operator<<(ostream &os, vector<T> &v) {
  for (int i = 0; i < v.size(); os << (i > 0 ? " " : "") << v[i++])
    ;
  return os;
}
using t3 = tuple<int, int, int>;
const int inf = 1e9 + 10;
pair<int, int> locate(int rx, int cy, vector<pair<int, int>> const &rg,
                      vector<pair<int, int>> &cg) {
  auto rl = lower_bound(rg.begin(), rg.end(), make_pair(rx, rx));
  int rans = rl - rg.begin();
  auto cl = lower_bound(cg.begin(), cg.end(), make_pair(cy, cy));
  int cans = cl - cg.begin();
  return {rans, cans};
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  set<int> rc, cc;
  rc.insert(0);
  cc.insert(0);
  vector<t3> hl, vector<long long>;
  int i, j, a, b, c;
  for (i = 0; i < n; i++) {
    cin >> a >> b >> c;
    a *= 2;
    b *= 2;
    c *= 2;
    vector<long long>.emplace_back(a, b, c);
    rc.insert(a);
    rc.insert(b);
    cc.insert(c);
  }
  for (i = 0; i < m; i++) {
    cin >> a >> b >> c;
    a *= 2;
    b *= 2;
    c *= 2;
    hl.emplace_back(b, c, a);
    rc.insert(a);
    cc.insert(b);
    cc.insert(c);
  }
  vector<int> rcv((rc).begin(), (rc).end());
  vector<int> ccv((cc).begin(), (cc).end());
  vector<pair<int, int>> rg;
  rg.push_back({-inf, rcv[0] - 1});
  for (i = 0; i < rcv.size(); i++) {
    rg.push_back({rcv[i], rcv[i]});
    if (i + 1 < rcv.size()) {
      rg.push_back({rcv[i] + 1, rcv[i + 1] - 1});
    }
  }
  rg.push_back({rcv.back() + 1, +inf});
  int nr = rg.size();
  vector<pair<int, int>> cg;
  cg.push_back({-inf, ccv[0] - 1});
  for (i = 0; i < ccv.size(); i++) {
    cg.push_back({ccv[i], ccv[i]});
    if (i + 1 < ccv.size()) {
      cg.push_back({ccv[i] + 1, ccv[i + 1] - 1});
    }
  }
  cg.push_back({ccv.back() + 1, +inf});
  int nc = cg.size();
  vector<vector<bool>> grid(nr, vector<bool>(nc, false));
  for (i = 0; i < n; i++) {
    tie(a, b, c) = vector<long long>[i];
    int rr, cc;
    tie(rr, cc) = locate(a, c, rg, cg);
    while (rg[rr].second <= b) {
      grid[rr][cc] = true;
      rr++;
    }
  }
  for (i = 0; i < m; i++) {
    tie(a, b, c) = hl[i];
    int rr, cc;
    tie(rr, cc) = locate(c, a, rg, cg);
    while (cg[cc].second <= b) {
      grid[rr][cc] = true;
      cc++;
    }
  }
  long long ans = 0;
  stack<pair<int, int>> q;
  vector<vector<bool>> clr(nr, vector<bool>(nc, false));
  int ri, ci;
  tie(ri, ci) = locate(0, 0, rg, cg);
  clr[ri][ci] = true;
  q.push({ri, ci});
  bool isInf = false;
  vector<pair<int, int>> dir = {{0, 1},  {-1, 0},  {0, -1}, {1, 0},
                                {-1, 1}, {-1, -1}, {1, -1}, {1, 1}};
  while (!q.empty()) {
    tie(ri, ci) = q.top();
    q.pop();
    if (ri == 0 || ri == nr - 1 || ci == 0 || ci == nc - 1) {
      isInf = true;
      break;
    }
    long long h = max(long long(rg[ri].second) - rg[ri].first + 1, 1ll);
    long long w = max(long long(cg[ci].second) - cg[ci].first + 1, 1ll);
    ans += h * w;
    for (auto dd : dir) {
      int rnew = ri + dd.first;
      int cnew = ci + dd.second;
      if (rnew < 0 || rnew > nr - 1 || ci < 0 || ci > nc - 1 ||
          grid[rnew][cnew] || clr[rnew][cnew]) {
        continue;
      }
      clr[rnew][cnew] = true;
      q.push({rnew, cnew});
    }
  }
  if (isInf) {
    cout << "INF\n";
  } else {
    cout << (ans / 2) << "\n";
  }
  return 0;
}
