#include <bits/stdc++.h>
using namespace std;
template <typename A, typename B>
ostream &operator<<(ostream &cout, pair<A, B> const &p) {
  return cout << "(" << p.first << ", " << p.second << ")";
}
template <typename A>
ostream &operator<<(ostream &cout, vector<A> const &v) {
  cout << "{";
  for (int i = 0; i < v.size(); i++) {
    if (i) cout << ", ";
    cout << v[i];
  }
  return cout << "}";
}
const int INF = 2e9;
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  vector<pair<pair<int, int>, int>> hori(m), vert(n);
  set<int> xs, ys;
  xs.insert(-INF);
  ys.insert(-INF);
  for (int i = 0; i < n; i++) {
    cin >> vert[i].first.first >> vert[i].first.second >> vert[i].second;
    xs.insert(vert[i].second);
    ys.insert(vert[i].first.first);
    ys.insert(vert[i].first.second);
  }
  for (int i = 0; i < m; i++) {
    cin >> hori[i].second >> hori[i].first.first >> hori[i].first.second;
    ys.insert(hori[i].second);
    xs.insert(hori[i].first.first);
    xs.insert(hori[i].first.second);
  }
  map<int, int> mx, my;
  vector<int> xord, yord;
  int cnt = 0;
  for (int val : xs) {
    mx[val] = cnt;
    xord.push_back(val);
    cnt++;
  }
  cnt = 0;
  for (int val : ys) {
    my[val] = cnt;
    yord.push_back(val);
    cnt++;
  }
  int sx = mx.size();
  int sy = my.size();
  const int MAX = 3010;
  bool go[MAX][MAX][4];
  bool vis[MAX][MAX];
  int dx[4] = {0, 0, 1, -1};
  int dy[4] = {1, -1, 0, 0};
  for (int i = 0; i < MAX; i++) {
    for (int j = 0; j < MAX; j++) {
      for (int d = 0; d < 4; d++) {
        go[i][j][d] = true;
      }
      vis[i][j] = false;
    }
  }
  for (auto h : hori) {
    int st = mx[h.first.first];
    int ed = mx[h.first.second] - 1;
    int edge = my[h.second];
    for (int i = st; i <= ed; i++) {
      go[i][edge - 1][0] = false;
      go[i][edge][1] = false;
      assert(edge > 0);
    }
  }
  for (auto v : vert) {
    int st = my[v.first.first];
    int ed = my[v.first.second] - 1;
    int edge = mx[v.second];
    for (int i = st; i <= ed; i++) {
      go[edge - 1][i][2] = false;
      go[edge][i][3] = false;
      assert(edge > 0);
    }
  }
  int xx = mx[*prev(xs.upper_bound(0))];
  int yy = my[*prev(ys.upper_bound(0))];
  auto valid = [&](int a, int b) -> bool {
    return a >= 0 && a < sx && b >= 0 && b < sy;
  };
  bool inf = false;
  function<void(int, int)> dfs = [&](int x, int y) {
    vis[x][y] = true;
    if (x == 0 || y == 0 || x == sx - 1 || y == sy - 1) {
      inf = true;
    }
    for (int d = 0; d < 4; d++) {
      if (!go[x][y][d]) continue;
      int nx = x + dx[d];
      int ny = y + dy[d];
      if (!valid(nx, ny) || vis[nx][ny]) continue;
      dfs(nx, ny);
    }
  };
  dfs(xx, yy);
  if (inf) {
    cout << "INF" << '\n';
    return 0;
  }
  long long ans = 0;
  for (int i = 0; i < sx; i++) {
    for (int j = 0; j < sy; j++) {
      if (!vis[i][j]) continue;
      long long x = xord[i + 1] - xord[i];
      long long y = yord[j + 1] - yord[j];
      ans += x * y;
    }
  }
  cout << ans << '\n';
  return 0;
}
