#include <bits/stdc++.h>
using namespace std;
template <class c>
struct rge {
  c b, e;
};
template <class c>
rge<c> range(c i, c j) {
  return rge<c>{i, j};
}
template <class c>
auto dud(c* x) -> decltype(cerr << *x, 0);
template <class c>
char dud(...);
struct debug {
  template <class c>
  debug& operator<<(const c&) {
    return *this;
  }
};
const int N = 6060;
const int Inf = 1e9 + 1;
struct NS {
  int x1, x2, y;
  NS(int x1 = 0, int x2 = 0, int y = 0) : x1(x1), x2(x2), y(y) {}
  void Read() { scanf("%d%d%d", &x1, &x2, &y); }
};
struct EW {
  int x, y1, y2;
  EW(int x = 0, int y1 = 0, int y2 = 0) : x(x), y1(y1), y2(y2) {}
  void Read() { scanf("%d%d%d", &x, &y1, &y2); }
};
int Cx, Cy;
vector<int> P;
int Hash(int x, int y) { return x * Cy + y; }
pair<int, int> DeHash(int v) { return make_pair(v / Cy, v % Cy); }
void Init() {
  P.assign(Cx * Cy, 0);
  for (int x = 0; x < Cx; x++)
    for (int y = 0; y < Cy; y++) P[Hash(x, y)] = Hash(x, y);
}
int F(int v) { return v == P[v] ? v : P[v] = F(P[v]); }
bool Same(int v, int w) { return F(v) == F(w); }
void Un(int v, int w) {
  if ((v = F(v)) == (w = F(w))) return;
  P[v] = w;
}
int main() {
  int n, m;
  cin >> n >> m;
  vector<NS> A(n);
  vector<EW> B(m);
  for (int i = 0; i < n; i++) A[i].Read();
  for (int j = 0; j < m; j++) B[j].Read();
  map<int, int> Axis;
  Axis[-Inf], Axis[0], Axis[+Inf];
  for (int i = 0; i < n; i++)
    Axis[A[i].x1 - 1], Axis[A[i].x1], Axis[A[i].x2], Axis[A[i].x2 + 1];
  for (int j = 0; j < m; j++) Axis[B[j].x - 1], Axis[B[j].x], Axis[B[j].x + 1];
  for (pair<int, int> p : Axis) Axis[p.first] = Cx++;
  map<int, int> Ayis;
  Ayis[-Inf], Ayis[0], Ayis[+Inf];
  for (int i = 0; i < n; i++) Ayis[A[i].y - 1], Ayis[A[i].y], Ayis[A[i].y + 1];
  for (int j = 0; j < m; j++)
    Ayis[B[j].y1 - 1], Ayis[B[j].y1], Ayis[B[j].y2], Ayis[B[j].y2 + 1];
  for (pair<int, int> p : Ayis) Ayis[p.first] = Cy++;
  vector<int> X;
  vector<int> Y;
  for (pair<int, int> p : Axis) X.push_back(p.first);
  for (pair<int, int> p : Ayis) Y.push_back(p.first);
  assert(X.size() == Cx);
  assert(Y.size() == Cy);
  Init();
  vector<vector<bool>> G(Cx, vector<bool>(Cy, true));
  debug() << " ["
          << "Axis"
             ": "
          << (Axis) << "] ";
  debug() << " ["
          << "Ayis"
             ": "
          << (Ayis) << "] ";
  for (int i = 0; i < n; i++) {
    A[i].x1 = Axis[A[i].x1];
    A[i].x2 = Axis[A[i].x2];
    A[i].y = Ayis[A[i].y];
  }
  for (int j = 0; j < m; j++) {
    B[j].x = Axis[B[j].x];
    B[j].y1 = Ayis[B[j].y1];
    B[j].y2 = Ayis[B[j].y2];
  }
  for (int i = 0; i < n; i++)
    for (int y = A[i].y, x = A[i].x1; x <= A[i].x2; x++) G[x][y] = false;
  for (int j = 0; j < m; j++)
    for (int x = B[j].x, y = B[j].y1; y <= B[j].y2; y++) G[x][y] = false;
  for (int x = 0; x < Cx; x++) {
    for (int y = 0; y < Cy; y++) {
      if (G[x][y]) {
        if (x > 0 && G[x - 1][y]) Un(Hash(x - 1, y), Hash(x, y));
        if (x + 1 < Cx && G[x + 1][y]) Un(Hash(x + 1, y), Hash(x, y));
        if (y > 0 && G[x][y - 1]) Un(Hash(x, y - 1), Hash(x, y));
        if (y + 1 < Cy && G[x][y + 1]) Un(Hash(x, y + 1), Hash(x, y));
      }
    }
  }
  if (Same(Hash(Axis[0], Ayis[0]), Hash(Axis[-Inf], Ayis[-Inf])))
    return 0 * puts("INF");
  long long Ans = 0;
  for (int x = 1; x < Cx; x++) {
    for (int y = 1; y < Cy; y++) {
      if (Same(Hash(Axis[0], Ayis[0]), Hash(x, y))) {
        Ans += (long long)(X[x] - X[x - 1]) * (Y[y] - Y[y - 1]);
      }
    }
  }
  cout << Ans << endl;
}
