#include <bits/stdc++.h>
#define inf (long long)(1e18)
using namespace std;

struct Unionfind {
  // tree number
  vector<int> par;
  // constructor
  Unionfind(int n = 1) : par(n, -1) {}
  // search root
  int root(int x) {
    if (par[x] < 0) return x;
    return par[x] = root(par[x]);
  }
  // is same?
  bool issame(int x, int y) { return root(x) == root(y); }

  // add
  // already added, return 0
  bool uni(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) return 0;
    if (par[x] > par[y]) swap(x, y);
    par[x] += par[y];
    par[y] = x;
    return 1;
  }
  int size(int x) { return -par[root(x)]; }
};

struct line {
  long long a, b, c;
};

long long n, m;
map<long long, long long> mpx, mpy;
vector<line> r, c;
vector<long long> x, y;
vector<vector<long long>> memox, memoy;

long long solve();

int main() {
  cin >> n >> m;
  r.resize(m);
  c.resize(n);
  for (int i = 0; i < n; ++i) {
    cin >> c[i].a >> c[i].b >> c[i].c;
    x.push_back(c[i].c);
    y.push_back(c[i].a);
    y.push_back(c[i].b);
  }
  for (int i = 0; i < m; ++i) {
    cin >> r[i].c >> r[i].a >> r[i].b;
    y.push_back(r[i].c);
    x.push_back(r[i].a);
    x.push_back(r[i].b);
  }
  x.push_back(-inf);
  x.push_back(inf);
  x.push_back(0);
  y.push_back(-inf);
  y.push_back(inf);
  y.push_back(0);
  sort(x.begin(), x.end());
  sort(y.begin(), y.end());
  x.erase(unique(x.begin(), x.end()), x.end());
  y.erase(unique(y.begin(), y.end()), y.end());
  for (int i = 0; i < x.size(); ++i) mpx[x[i]] = i;
  for (int i = 0; i < y.size(); ++i) mpy[y[i]] = i;
  long long res = solve();
  if (res < 0)
    cout << "INF" << endl;
  else
    cout << res << endl;
  return 0;
}

long long solve() {
  long long res = 0, lenx = x.size(), leny = y.size();
  memox.assign(leny + 1, vector<long long>(lenx + 1, 0));
  memoy.assign(leny + 1, vector<long long>(lenx + 1, 0));
  for (int i = 0; i < n; ++i) {
    auto l = c[i];
    ++memoy[mpy[l.a]][mpx[l.c]];
    --memoy[mpy[l.b]][mpx[l.c]];
  }
  for (int i = 1; i < leny; ++i)
    for (int j = 0; j < lenx; ++j) memoy[i][j] += memoy[i - 1][j];
  for (int i = 0; i < m; ++i) {
    auto l = r[i];
    ++memox[mpy[l.c]][mpx[l.a]];
    --memox[mpy[l.c]][mpx[l.b]];
  }
  for (int i = 0; i < leny; ++i)
    for (int j = 1; j < lenx; ++j) memox[i][j] += memox[i][j - 1];
  Unionfind uf(lenx * leny);
  for (int i = 0; i < leny; ++i)
    for (int j = 0; j < lenx; ++j) {
      if (memoy[i][j] <= 0 && j > 0) uf.uni(i * lenx + j, i * lenx + j - 1);
      if (memox[i][j] <= 0 && i > 0) uf.uni(i * lenx + j, (i - 1) * lenx + j);
    }
  vector<int> v;
  int zerox = mpx[0], zeroy = mpy[0];
  v.push_back(zeroy * lenx + zerox);
  // if (zeroy > 0) v.push_back((zeroy - 1) * lenx + zerox);
  // if (zerox > 0) v.push_back(zeroy * lenx + zerox - 1);
  // if (zeroy > 0 && zerox > 0) v.push_back((zeroy - 1) * lenx + zerox - 1);
  for (int i = 0; i < leny - 1; ++i)
    for (int j = 0; j < lenx - 1; ++j) {
      bool ch = 0;
      for (auto p : v) ch |= uf.issame(p, i * lenx + j);
      if (ch) {
        if (i == 0 || j == 0 || i == leny - 1 || j == lenx - 1) return -1;
        res += (y[i + 1] - y[i]) * (x[j + 1] - x[j]);
      }
    }
  return res;
}

Measured memory_bytes: 180164