#include <bits/stdc++.h>
using namespace std;
template <class T1, class T2>
ostream& operator<<(ostream& out, const pair<T1, T2> p) {
  out << '(' << p.first << ',' << p.second << ')';
  return out;
}
template <class T1, class T2>
istream& operator>>(istream& in, pair<T1, T2>& p) {
  in >> p.first >> p.second;
  return in;
}
template <class T>
istream& operator>>(istream& in, vector<T>& v) {
  for (T& x : v) in >> x;
  return in;
}
template <class T>
ostream& operator<<(ostream& out, const vector<vector<T>>& v) {
  for (const vector<T>& x : v) out << x << '\n';
  return out;
}
template <class T>
ostream& operator<<(ostream& out, const vector<T>& v) {
  for (const T& x : v) out << x << ' ';
  return out;
}
long long gcd(long long a, long long b) {
  if (b > a) swap(a, b);
  return (b ? gcd(b, a % b) : a);
}
using ll = long long;
using pii = pair<int, int>;
using pll = pair<long long, long long>;
using tiii = pair<pair<int, int>, int>;
using vi = vector<int>;
using vl = vector<long long>;
using vvi = vector<vector<int>>;
using vvl = vector<vector<long long>>;
const int h = 1000000007;
signed main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  cerr.setstate(ios::failbit);
  int n, m;
  cin >> n >> m;
  vector<tiii> vert(n), horz(m);
  cin >> vert >> horz;
  set<int> all_points;
  for (tiii t : vert)
    all_points.insert({t.first.first, t.first.second, t.second});
  for (tiii t : horz)
    all_points.insert({t.first.first, t.first.second, t.second});
  all_points.insert(0);
  all_points.insert(int(1e9) + 1);
  all_points.insert(-int(1e9) - 1);
  vi points(all_points.begin(), all_points.end());
  vvi grid(2 * points.size() - 1, vi(2 * points.size() - 1));
  map<int, int> index;
  int in = 0;
  for (int point : points) index[point] = in++;
  for (tiii t : vert) {
    int si = 2 * index[t.first.first];
    int ei = 2 * index[t.first.second];
    int j = 2 * index[t.second];
    for (int i = si; i <= ei; i++) grid[i][j] = 1;
  }
  for (tiii t : horz) {
    int i = 2 * index[t.first.first];
    int sj = 2 * index[t.first.second];
    int ej = 2 * index[t.second];
    for (int j = sj; j <= ej; j++) grid[i][j] = 1;
  }
  grid[2 * index[0]][2 * index[0]] = 1;
  stack<pii> st;
  st.push({2 * index[0], 2 * index[0]});
  vector<pii> dir{{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
  while (!st.empty()) {
    pii cur = st.top();
    st.pop();
    for (auto d : dir) {
      pii nex = {cur.first + d.first, cur.second + d.second};
      if (nex.first < 0 or nex.second < 0 or nex.first == grid.size() or
          nex.second == grid.size())
        continue;
      if (!grid[nex.first][nex.second]) {
        grid[nex.first][nex.second] = 1;
        st.push(nex);
      }
    }
  }
  for (int i = (0); i < (grid.size()); i++)
    if (grid[0][i] or grid[grid.size() - 1][0] or grid[i][0] or
        grid[0][grid.size() - 1])
      return cout << "INF", 0;
  ;
  ll ans = 0;
  for (int i = (0); i < (points.size() - 1); i++)
    for (int j = (0); j < (points.size() - 1); j++) {
      bool Y = true;
      for (int x = 2 * i; x <= 2 * i + 2; x++)
        for (int y = 2 * j; y <= 2 * j + 2; y++)
          if (!grid[x][y]) Y = false;
      if (Y) ans += ll(points[i + 1] - points[i]) * (points[j + 1] - points[j]);
    }
  cout << ans;
}
