#include <bits/stdc++.h>
#include <cassert>
typedef long long int ll;
using namespace std;

// @@ !! LIM(binsearch)
// --> binsearch
// ---- inserted library file binsearch.cc

template<typename T>
T binsearch(auto check, T yes, T no, T err = (T)1) {
  while (abs(yes - no) > err) {
    T mid = (yes + no) / (T)2;
    if (check(mid)) yes = mid;
    else            no  = mid;
  }
  return yes;
}

// ---- end binsearch.cc
// @@ !! LIM  -- end mark --

int main(int argc, char *argv[]) {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout << setprecision(20);

  ll N, M; cin >> N >> M;
  vector<ll> A(N), B(N), C(N), D(M), E(M), F(M);
  for (ll i = 0; i < N; i++) cin >> A.at(i) >> B.at(i) >> C.at(i);
  for (ll i = 0; i < M; i++) cin >> D.at(i) >> E.at(i) >> F.at(i);
  vector<ll> row, col;
  for (ll i = 0; i < N; i++) {
    row.push_back(A.at(i));
    row.push_back(B.at(i));
    col.push_back(C.at(i));
  }
  for (ll i = 0; i < M; i++) {
    row.push_back(D.at(i));
    col.push_back(E.at(i));
    col.push_back(F.at(i));
  }
  sort(row.begin(), row.end());
  sort(col.begin(), col.end());
  map<ll, ll> mp_row, mp_col;
  vector<ll> len_row, len_col;
  ll idx = 0;
  for (ll i = 0; i < (ll)row.size(); i++) {
    if (i == 0 || row.at(i-1) != row.at(i)) {
      mp_row[row.at(i)] = idx;
      if (i-1 > 0) {
	len_row.push_back(row.at(i) - row.at(i-1));
      }
      idx++;
    }
  }
  ll row_size = idx;
  idx = 0;
  for (ll i = 0; i < (ll)col.size(); i++) {
    if (i == 0 || col.at(i-1) != col.at(i)) {
      mp_col[col.at(i)] = idx;
      if (i-1 > 0) {
	len_col.push_back(col.at(i) - col.at(i-1));
      }
      idx++;
    }
  }
  ll col_size = idx;
  
  using Pair = pair<ll, ll>;
  vector<vector<Pair>> horiz(row_size), vert(col_size);
  for (ll i = 0; i < N; i++) {
    vert.at(mp_col.at(C.at(i))).emplace_back(mp_row.at(A.at(i)),
					     mp_row.at(B.at(i)));
  }
  for (ll i = 0; i < M; i++) {
    horiz.at(mp_row.at(D.at(i))).emplace_back(mp_col.at(E.at(i)),
					      mp_col.at(F.at(i)));
  }

  auto horiz_chk = [&](ll r, ll c) -> bool {
    auto prop = [&](ll j) -> bool { return horiz.at(r).at(j).first <= c; };
    ll j = binsearch<ll>(prop, -1, (ll)horiz.at(r).size());
    if (j < 0) return true;
    return horiz.at(r).at(j).second <= c;
  };

  auto vert_chk = [&](ll c, ll r) -> bool {
    auto prop = [&](ll j) -> bool { return vert.at(c).at(j).first <= r; };
    ll j = binsearch<ll>(prop, -1, (ll)vert.at(c).size());
    if (j < 0) return true;
    return vert.at(c).at(j).second <= r;
  };

  vector visited(row_size, vector(col_size, false));
  auto dfs = [&](const auto& recF, ll r, ll c) -> ll {
    if (r < 0 || c < 0 || r >= row_size || c >= col_size) return -1;
    if (visited.at(r).at(c)) return 0;
    visited.at(r).at(c) = true;
    ll ans = len_row.at(r) * len_col.at(c);
    if (horiz_chk(r, c)) {
      ll t = recF(recF, r-1, c);
      if (t < 0) return -1;
      ans += t;
    }
    if (horiz_chk(r+1, c)) {
      ll t = recF(recF, r+1, c);
      if (t < 0) return -1;
      ans += t;
    }
    if (vert_chk(c, r)) {
      ll t = recF(recF, r, c-1);
      if (t < 0) return -1;
      ans += t;
    }
    if (vert_chk(c+1, r)) {
      ll t = recF(recF, r, c+1);
      if (t < 0) return -1;
      ans += t;
    }
    return ans;
  };
  ll ans = dfs(dfs, mp_row[0], mp_col[0]);
  if (ans < 0) {
    cout << "INF\n";
  }else {
    cout << ans << endl;
  }

  return 0;
}

