#include <algorithm>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <tuple>
#include <vector>

using namespace std;

#define rep(i, n) for (int64_t i = 0; i < (n); i++)
#define irep(i, n) for (int64_t i = 0; i <= (n); i++)
#define rrep(i, n) for (int64_t i = (n)-1; i >= 0; i--)
#define rirep(i, n) for (int64_t i = n; i >= 0; i--)

int main() {
  int n, m;
  cin >> n >> m;

  using S = tuple<int, int, int>;
  vector<S> vseg, hseg;
  vector<int> x, y;
  rep(i, n) {
    int a, b, c;
    cin >> a >> b >> c;

    vseg.push_back(S(a, b, c));
    x.push_back(a);
    x.push_back(b);
    y.push_back(c);
  }

  rep(i, m) {
    int d, e, f;
    cin >> d >> e >> f;

    hseg.push_back(S(d, e, f));
    x.push_back(d);
    y.push_back(e);
    y.push_back(f);
  }

  const int MIN = -1e9 - 1, MAX = 1e9 + 1;
  x.push_back(0);
  x.push_back(MIN);
  x.push_back(MAX);
  y.push_back(0);
  y.push_back(MIN);
  y.push_back(MAX);

  sort(x.begin(), x.end());
  x.erase(unique(x.begin(), x.end()), x.end());
  sort(y.begin(), y.end());
  y.erase(unique(y.begin(), y.end()), y.end());

  const int H = x.size(), W = y.size();
  vector<vector<bool>> accessible(H * 2, vector<bool>(W * 2, true));
  for (auto s : vseg) {
    int a, b, c;
    tie(a, b, c) = s;

    int lidx = lower_bound(x.begin(), x.end(), a) - x.begin();
    int ridx = lower_bound(x.begin(), x.end(), b) - x.begin();
    int cidx = lower_bound(y.begin(), y.end(), c) - y.begin();
    for (int i = lidx; i < ridx; i++) {
      accessible[2 * i][2 * cidx - 1] = false;
    }
  }
  for (auto s : hseg) {
    int d, e, f;
    tie(d, e, f) = s;

    int cidx = lower_bound(x.begin(), x.end(), d) - x.begin();
    int lidx = lower_bound(y.begin(), y.end(), e) - y.begin();
    int ridx = lower_bound(y.begin(), y.end(), f) - y.begin();
    for (int i = lidx; i < ridx; i++) {
      accessible[2 * cidx - 1][2 * i] = false;
    }
  }

  vector<vector<bool>> isVisited(H, vector<bool>(W, false));
  int64_t result = 0;

  using P = pair<int, int>;
  queue<P> q;
  int si = lower_bound(x.begin(), x.end(), 0) - x.begin();
  int sj = lower_bound(y.begin(), y.end(), 0) - y.begin();

  q.push(P(si, sj));
  isVisited[si][sj] = true;
  while (!q.empty()) {
    int i, j;
    tie(i, j) = q.front();
    q.pop();

    if (i + 1 < H && j + 1 < W) {
      result += ((int64_t)x[i + 1] - x[i]) * (y[j + 1] - y[j]);
    }

    for (int di = -1; di <= 1; di++) {
      for (int dj = -1; dj <= 1; dj++) {
        if (abs(di) + abs(dj) == 1) {
          int ni = i + di, nj = j + dj;
          if (ni >= 0 && ni < H && nj >= 0 && nj < W && !isVisited[ni][nj]) {
            if (accessible[(2 * ni + 2 * i) / 2][(2 * nj + 2 * j) / 2]) {
              isVisited[ni][nj] = true;
              q.push(P(ni, nj));
            }
          }
        }
      }
    }
  }

  if (isVisited[0][0]) {
    cout << "INF" << endl;
  } else {
    cout << result << endl;
  }

  return 0;
}