#include <bits/stdc++.h>
#include <boost/format.hpp>
#include <boost/integer/common_factor_rt.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/optional.hpp>

#ifdef DEBUG
#include "libs/debug.cpp"
#define DEBUG 1
#else
#define DEBUG 0
#endif

#define rep(i, n) repr((i), 0, (n))
#define repr(i, a, t) reps((i), (a), (t), 1)
#define reps(i, a, t, s) for (long long (i) = (a); (i) < (long long)(t); (i) += (s))
#define rrep(i, n) rrepr((i), (n), 0)
#define rrepr(i, a, t) rreps((i), (a), (t), 1)
#define rreps(i, a, t, s) for (long long (i) = (a) - 1; (i) >= (long long)(t); (i) -= (s))
#define each(v, c) for (auto &&(v) : (c))
#define all(c) (c).begin(), (c).end()

using namespace std;
namespace mp = boost::multiprecision;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using ml = mp::cpp_int;
template<typename T>
using optional = boost::optional<T>;
const auto none = boost::none;
const long long MOD = 1e9 + 7;
const long long INF = 1e18;

int main() {
  cout << fixed << setprecision(10);
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  ifstream ifs;
  if (DEBUG) {
    ifs.open("src/_in.txt");
    cin.rdbuf(ifs.rdbuf());
  }

  ll N, M;
  cin >> N >> M;
  vector<tuple<ll, ll, ll>> ABX(N);
  rep (i, N) {
    cin >> get<0>(ABX[i]) >> get<1>(ABX[i]) >> get<2>(ABX[i]);
  }
  vector<tuple<ll, ll, ll>> YEF(M);
  rep (i, M) {
    cin >> get<0>(YEF[i]) >> get<1>(YEF[i]) >> get<2>(YEF[i]);
  }
  vector<ll> X, Y;

  each (abx, ABX) {
    auto[a, b, x] = abx;
    X.push_back(x);
    Y.push_back(a);
    Y.push_back(b);
  }
  each(yef, YEF) {
    auto[y, e, f] = yef;
    X.push_back(e);
    X.push_back(f);
    Y.push_back(y);
  }

  sort(all(X));
  X.erase(unique(all(X)), X.end());
  sort(all(Y));
  Y.erase(unique(all(Y)), Y.end());

  rep (i, 10) {
    X.insert(X.begin(), -INF);
    Y.insert(Y.begin(), -INF);
    X.push_back(INF);
    Y.push_back(INF);
  }

  vector<vector<bool>> v_lines(X.size(), vector<bool>(Y.size(), false));
  vector<vector<bool>> h_lines(X.size(), vector<bool>(Y.size(), false));
  each (abx, ABX) {
    auto[a, b, x] = abx;
    ll l = lower_bound(all(Y), min(a, b)) - Y.begin();
    ll r = lower_bound(all(Y), max(a, b)) - Y.begin();
    ll xi = lower_bound(all(X), x) - X.begin();
    repr (yi, l, r) {
      v_lines[xi][yi] = true;
    }
  }
  each (yef, YEF) {
    auto[y, e, f] = yef;
    ll l = lower_bound(all(X), min(e, f)) - X.begin();
    ll r = lower_bound(all(X), max(e, f)) - X.begin();
    ll yi = lower_bound(all(Y), y) - Y.begin();
    repr (xi, l, r) {
      h_lines[xi][yi] = true;
    }
  }

  ll xi = (upper_bound(all(X), 0ll) - X.begin()) - 1;
  ll yi = (upper_bound(all(Y), 0ll) - Y.begin()) - 1;
  ll s = 0;
  vector<vector<bool>> seen(X.size(), vector<bool>(Y.size(), false));
  seen[xi][yi] = true;
  vector<tuple<ll, ll>> stack;
  stack.emplace_back(xi, yi);
  int dx4[] = {0, 1, 0, -1};
  int dy4[] = {1, 0, -1, 0};
  bool inf = false;
  while (!stack.empty() && !inf) {
    tie(xi, yi) = stack.back();
    stack.pop_back();
    s += (X[xi + 1] - X[xi]) * (Y[yi + 1] - Y[yi]);
    if (xi < 5 || yi < 5 || X.size() - 5 < xi || Y.size() - 5 < yi) inf = true;
    rep (i, 4) {
      int dx = dx4[i];
      int dy = dy4[i];
      ll xj = xi + dx;
      ll yj = yi + dy;
      if (seen[xj][yj]) continue;
      if (i == 0 && h_lines[xi][yi + 1]) continue;
      if (i == 1 && v_lines[xi + 1][yi]) continue;
      if (i == 2 && h_lines[xi][yi]) continue;
      if (i == 3 && v_lines[xi][yi]) continue;
      seen[xj][yj] = true;
      stack.emplace_back(xj, yj);
    }
  }
  if (!inf) {
    cout << s << endl;
  } else {
    cout << "INF" << endl;
  }
}

Measured memory_bytes: 73004