#include <bits/stdc++.h>
using namespace std;
template <typename T>
istream &operator>>(istream &is, vector<T> &vec) {
  for (T &x : vec) is >> x;
  return is;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, pair<T, U> &pair_var) {
  os << "(" << pair_var.first << ", " << pair_var.second << ")";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "{";
  for (int i = 0; i < vec.size(); i++) {
    os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
  }
  os << "}";
  return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, map<T, U> &map_var) {
  os << "{";
  for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
    os << *itr;
    itr++;
    if (itr != map_var.end()) os << ", ";
    itr--;
  }
  os << "}";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, set<T> &set_var) {
  os << "{";
  for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
    os << *itr;
    itr++;
    if (itr != set_var.end()) os << ", ";
    itr--;
  }
  os << "}";
  return os;
}
void dump_func() { cerr << endl; }
template <class Head, class... Tail>
void dump_func(Head &&head, Tail &&...tail) {
  cerr << head;
  if (sizeof...(Tail) > 0) {
    cerr << ", ";
  }
  dump_func(std::move(tail)...);
}
using P = pair<int, int>;
void inf() {
  cout << "INF" << endl;
  exit(0);
}
int main() {
  int n, m;
  cin >> n >> m;
  int a[n], b[n], c[n], d[n], e[n], f[n];
  set<int> xp, yp;
  xp.insert(0);
  yp.insert(0);
  for (int i = 1; i <= n; i++) {
    cin >> a[i] >> b[i] >> c[i];
    xp.insert(a[i]);
    xp.insert(b[i]);
    yp.insert(c[i]);
  }
  for (int i = 1; i <= m; i++) {
    cin >> d[i] >> e[i] >> f[i];
    xp.insert(d[i]);
    yp.insert(e[i]);
    yp.insert(f[i]);
  }
  int xsize = xp.size();
  int ysize = yp.size();
  bool visited[xsize + 1][ysize + 1];
  bool top[xsize + 1][ysize + 1];
  bool left[xsize + 1][ysize + 1];
  for (int x = 0; x < xsize + 1; x++) {
    for (int y = 0; y < ysize + 1; y++) {
      visited[x][y] = false;
      top[x][y] = false;
      left[x][y] = false;
    }
  }
  map<int, int> xi2d, yi2d;
  map<int, int> xd2i, yd2i;
  int i = 0;
  for (auto d : xp) {
    xi2d[i] = d;
    xd2i[d] = i;
    i++;
  }
  i = 0;
  for (auto d : yp) {
    yi2d[i] = d;
    yd2i[d] = i;
    i++;
  }
  for (int i = 1; i <= n; i++) {
    int yi = yd2i[c[i]];
    for (int xi = xd2i[a[i]]; xi < xd2i[b[i]]; xi++) {
      top[xi][yi] = true;
    }
  }
  for (int i = 1; i <= n; i++) {
    int xi = xd2i[d[i]];
    for (int yi = yd2i[e[i]]; yi < yd2i[f[i]]; yi++) {
      left[xi][yi] = true;
    }
  }
  int ans = 0;
  queue<P> que;
  que.push({xd2i[0], yd2i[0]});
  while (!que.empty()) {
    P p = que.front();
    int x = p.first;
    int y = p.second;
    que.pop();
    if (visited[x][y]) continue;
    ans += (xi2d[x + 1] - xi2d[x]) * (yi2d[y + 1] - yi2d[y]);
    visited[x][y] = true;
    if (!left[x][y]) {
      int tx = x - 1;
      if (tx < 0) inf();
      que.push({tx, y});
    }
    if (!top[x][y]) {
      int ty = y - 1;
      if (ty < 0) inf();
      que.push({x, ty});
    }
    if (!left[x + 1][y]) {
      int tx = x + 1;
      if (tx == xsize - 1) inf();
      que.push({tx, y});
    }
    if (!top[x][y + 1]) {
      int ty = y + 1;
      if (ty == ysize - 1) inf();
      que.push({x, ty});
    }
  }
  cout << ans << endl;
}
