#include <bits/stdc++.h>
using namespace std;
const int maxint = (int)1e10;
using ll = long long;
struct ufind {
  vector<int> uf;
  ufind(int q) {
    uf = vector<int>(q);
    for (int i = 0; i < q; i++) uf.at(i) = i;
  }
  void stick(int a, int b) {
    if (uf.at(a) == uf.at(b)) return;
    int ma = fpe(a);
    int mb = fpe(b);
    int minx = (ma < mb) ? ma : mb;
    uf.at(ma) = minx;
    uf.at(mb) = minx;
    uf.at(a) = minx;
    uf.at(b) = minx;
  }
  int fpe(int a) { return (uf.at(a) == a) ? a : fpe(uf.at(a)); }
  bool find(int a, int b) { return fpe(a) == fpe(b); }
  bool find2(int a, int b) {
    if (uf.at(a) == uf.at(b)) return true;
    return fpe(a) == fpe(b);
  }
};
int findp(vector<int> v, int x) {
  auto it = lower_bound(v.begin(), v.end(), x);
  int pos = distance(v.begin(), it);
  return pos;
}
int main() {
  vector<int> gdx = {-maxint, maxint}, gdy = {-maxint, maxint};
  int N, M;
  cin >> N >> M;
  vector<int> Xv(N), Y1(N), Y2(N), X1(M), X2(M), Ys(M);
  for (int i = 0; i < N; i++) {
    cin >> Y1[i] >> Y2[i] >> Xv[i];
    gdx.push_back(Xv[i]);
    gdy.push_back(Y1[i]);
    gdy.push_back(Y2[i]);
  }
  for (int i = 0; i < M; i++) {
    cin >> Ys[i] >> X1[i] >> X2[i];
    gdy.push_back(Ys[i]);
    gdx.push_back(X1[i]);
    gdx.push_back(X2[i]);
  }
  sort(gdx.begin(), gdx.end());
  sort(gdy.begin(), gdy.end());
  gdx.erase(unique(gdx.begin(), gdx.end()), gdx.end());
  gdy.erase(unique(gdy.begin(), gdy.end()), gdy.end());
  vector<vector<int>> vline(gdy.size(), vector<int>(gdx.size(), 0));
  vector<vector<int>> sline(gdy.size(), vector<int>(gdx.size(), 0));
  for (int i = 0; i < N; i++) {
    int x0 = findp(gdx, Xv[i]);
    int y1 = findp(gdy, Y1[i]);
    int y2 = findp(gdy, Y2[i]);
    vline[y1][x0]++;
    vline[y2][x0]--;
  }
  for (int i = 0; i < M; i++) {
    int x1 = findp(gdx, X1[i]);
    int x2 = findp(gdx, X2[i]);
    int y0 = findp(gdy, Ys[i]);
    sline[y0][x1]++;
    sline[y0][x2]--;
  }
  int vy = gdy.size();
  int sx = gdx.size();
  ufind uf(gdx.size() * gdy.size());
  for (int y = 0; y < gdy.size(); y++) {
    for (int x = 0; x < gdx.size(); x++) {
      if (x) sline[y][x] += sline[y][x - 1];
      if (y) vline[y][x] += vline[y - 1][x];
      if (x && !vline[y][x]) uf.stick(y * sx + x, y * sx + x - 1);
      if (y && !sline[y][x]) uf.stick(y * sx + x, (y - 1) * sx + x);
    }
  }
  int rex, rey;
  for (int i = 0; i < sx; i++) {
    if (gdx.at(i) <= 0) {
      rex = i;
    } else {
      break;
    }
  }
  for (int i = 0; i < vy; i++) {
    if (gdy.at(i) <= 0) {
      rey = i;
    } else {
      break;
    }
  }
  int current = rey * sx + rex;
  if (uf.find2(current, 0)) {
    cout << "INF" << endl;
    return 0;
  }
  int area = 0;
  for (int i = 1; i < vy - 1; i++) {
    for (int j = 1; j < sx - 1; j++) {
      if (uf.find2(current, i * sx + j))
        area += (gdx[j + 1] - gdx[j]) * (gdy[i + 1] - gdy[i]);
    }
  }
  cout << area << endl;
}
