#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using P = pair<int, int>;
const double eps = 1e-8;
const ll MOD = 1000000007;
const int INF = INT_MAX / 2;
const ll LINF = LLONG_MAX / 2;
template <class T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> p) {
  os << p.first << ":" << p.second;
  return os;
}
template <class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  os << "[";
  for (int i = 0; i < (int)(v.size()); ++i) {
    if (i) os << ", ";
    os << v[i];
  }
  return os << "]";
}
void solve() {
  int N, M;
  cin >> N >> M;
  vector<int> A(N), B(N), C(N);
  vector<int> D(M), E(M), F(M);
  for (int i = 0; i < N; ++i) cin >> A[i] >> B[i] >> C[i];
  for (int i = 0; i < M; ++i) cin >> D[i] >> E[i] >> F[i];
  vector<int> xs, ys;
  xs.push_back(INF);
  xs.push_back(-INF);
  ys.push_back(INF);
  ys.push_back(-INF);
  for (int i = 0; i < N; ++i) {
    xs.push_back(A[i]);
    xs.push_back(B[i]);
    ys.push_back(C[i]);
  }
  for (int i = 0; i < M; ++i) {
    xs.push_back(D[i]);
    ys.push_back(E[i]);
    ys.push_back(F[i]);
  }
  sort(begin(xs), end(xs));
  xs.erase(unique(begin(xs), end(xs)), xs.end());
  sort(begin(ys), end(ys));
  ys.erase(unique(begin(ys), end(ys)), ys.end());
  int X = (int)(xs.size()) - 1;
  int Y = (int)(ys.size()) - 1;
  auto get_ix = [&](int x) -> int {
    auto pt = upper_bound(begin(xs), end(xs), x);
    return (int)(pt - xs.begin() - 1);
  };
  auto get_iy = [&](int y) -> int {
    auto pt = upper_bound(begin(ys), end(ys), y);
    return (int)(pt - ys.begin() - 1);
  };
  vector<vector<int>> grid(X, vector<int>(Y, 0));
  int dx[4] = {0, -1, 0, 1};
  int dy[4] = {-1, 0, 1, 0};
  for (int i = 0; i < N; ++i) {
    int y = get_iy(C[i]);
    int sx = get_ix(A[i]);
    int tx = get_ix(B[i]);
    for (int x = sx; x < tx; ++x) {
      grid[x][y - 1] |= 1 << 2;
      grid[x][y] |= 1 << 0;
    }
  }
  for (int i = 0; i < M; ++i) {
    int x = get_ix(D[i]);
    int sy = get_iy(E[i]);
    int st = get_iy(F[i]);
    for (int y = sy; y < st; ++y) {
      grid[x - 1][y] |= 1 << 3;
      grid[x][y] |= 1 << 1;
    }
  }
  ll ans = 0;
  vector<vector<bool>> reach(X, vector<bool>(Y, false));
  {
    reach[get_ix(0)][get_iy(0)] = true;
    queue<P> que;
    que.push(P(get_ix(0), get_iy(0)));
    if (get_ix(0) == 0 || get_iy(0) == 0 || get_ix(0) + 1 == X ||
        get_iy(0) + 1 == Y) {
      cerr << get_ix(0) << " " << get_iy(0) << endl;
      cout << "INF" << endl;
      return;
    }
    ll tmp = (xs[get_ix(0) + 1] - xs[get_ix(0)]) *
             (ys[get_iy(0) + 1] - ys[get_iy(0)]);
    ans += tmp;
    while (!que.empty()) {
      auto top = que.front();
      que.pop();
      int cx, cy;
      tie(cx, cy) = top;
      for (int k = 0; k < 4; ++k) {
        if (grid[cx][cy] >> k & 1) {
          continue;
        }
        int nx = cx + dx[k];
        int ny = cy + dy[k];
        if (nx == 0 || nx + 1 == X || ny == 0 || ny + 1 == Y) {
          cout << "INF" << endl;
          return;
        }
        if (!reach[nx][ny]) {
          reach[nx][ny] = true;
          que.push(P(nx, ny));
          ll tmp = (xs[nx + 1] - xs[nx]) * (ys[ny + 1] - ys[ny]);
          ans += tmp;
        }
      }
    }
  }
  cout << ans << endl;
}
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(10);
  solve();
  return 0;
}
