#include <bits/stdc++.h>
using namespace std;
template <class T1, class T2>
ostream& operator<<(ostream& os, const pair<T1, T2>& a) {
  return os << "(" << a.first << "," << a.second << ")";
}
template <class T>
void pv(T a, T b) {
  for (T i = a; i != b; ++i) cout << (*i) << " ";
  cout << endl;
}
template <class T>
void chmin(T& a, const T& b) {
  if (a > b) a = b;
}
template <class T>
void chmax(T& a, const T& b) {
  if (a < b) a = b;
}
int nextInt() {
  int x;
  scanf("%d", &x);
  return x;
}
long long nextLong() {
  long long x;
  scanf("%lld", &x);
  return x;
}
vector<long long> rev;
vector<int> normalize(const vector<long long> v) {
  const int N = v.size();
  vector<int> res(N);
  vector<pair<long long, int> > t(N);
  rev = vector<long long>(N);
  for (int i = 0, _n = (int)(N); i < _n; ++i) t[i] = {v[i], i};
  sort((t).begin(), (t).end());
  int r = 0;
  for (int i = 0, _n = (int)(N); i < _n; ++i) {
    r += (i > 0 && t[i - 1].first != t[i].first);
    res[t[i].second] = r;
    rev[r] = t[i].first;
  }
  return res;
}
const int SZ = 2000 * 3 * 2 + 10;
bool t[SZ][SZ];
bool vis[SZ][SZ];
int main2() {
  memset(t, (0), sizeof(t));
  memset(vis, (0), sizeof(vis));
  int N = nextInt();
  int M = nextInt();
  vector<long long> raw_input;
  for (int n = 0, _n = (int)(N); n < _n; ++n) {
    raw_input.push_back(nextInt());
    raw_input.push_back(nextInt());
    raw_input.push_back(nextInt());
  }
  for (int m = 0, _n = (int)(M); m < _n; ++m) {
    raw_input.push_back(nextInt());
    raw_input.push_back(nextInt());
    raw_input.push_back(nextInt());
  }
  raw_input.push_back(0);
  raw_input.push_back(1000000000 + 10);
  raw_input.push_back(-(1000000000 + 10));
  vector<int> input = normalize(raw_input);
  const int I = input.size();
  for (int i = 0; i < 3 * N; i += 3) {
    int A = 1 + 2 * input[i];
    int B = 1 + 2 * input[i + 1];
    int C = 1 + 2 * input[i + 2];
    for (int x = A; x <= B; x++) t[x][C] = true;
  }
  for (int i = 3 * N; i < 3 * N + 3 * M; i += 3) {
    int D = 1 + 2 * input[i];
    int E = 1 + 2 * input[i + 1];
    int F = 1 + 2 * input[i + 2];
    for (int x = E; x <= F; x++) t[D][x] = true;
  }
  const int dr[] = {0, 1, 0, -1};
  const int dc[] = {1, 0, -1, 0};
  bool inf = false;
  queue<int> q;
  int zero = input[3 * N + 3 * M] * 2;
  q.push(zero);
  q.push(zero);
  vis[zero][zero] = true;
  while (!q.empty()) {
    const int r = q.front();
    q.pop();
    const int c = q.front();
    q.pop();
    if (r <= 1 && c <= 1) {
      inf = true;
      break;
    }
    for (int i = 0, _n = (int)(4); i < _n; ++i) {
      const int nr = r + dr[i] * 2;
      const int nc = c + dc[i] * 2;
      if (!(0 <= nr && nr < 2 * I && 0 <= nc && nc < 2 * I)) continue;
      if (vis[nr][nc]) continue;
      if (t[r + dr[i]][c + dc[i]]) continue;
      vis[nr][nc] = true;
      q.push(nr);
      q.push(nc);
    }
  }
  if (inf) {
    cout << "INF" << endl;
  } else {
    long long ans = 0;
    for (int r = 0, _n = (int)(I); r < _n; ++r)
      for (int c = 0, _n = (int)(I); c < _n; ++c) {
        if (vis[2 * r][2 * c]) {
          ans += (rev[r + 1] - rev[r]) * (rev[c + 1] - rev[c]);
        }
      }
    cout << ans << endl;
  }
  return 0;
}
int main() {
  main2();
  return 0;
}
