#include <bits/stdc++.h>
using namespace std;
void parse_lines(const vector<long long> &C, const vector<long long> &vmin,
                 const vector<long long> &vmax, vector<long long> &coords,
                 vector<vector<pair<long long, long long>>> &intervals) {
  map<long long, vector<pair<long long, long long>>> L;
  long long N = long long((C).size()), i;
  for (i = (0); i < (N); ++i) {
    long long CC = C[i] * 2 + 1;
    if (L.find(CC) == L.end()) {
      L[CC] = vector<pair<long long, long long>>();
    }
    L[CC].push_back({vmin[i] * 2 + 1, vmax[i] * 2 + 1});
  }
  for (auto &l : L) {
    long long coord = l.first;
    coords.push_back(coord);
    vector<pair<long long, long long>> iv;
    sort((l.second).begin(), (l.second).end());
    long long v0 = l.second[0].first, v1 = l.second[0].second;
    for (i = (1); i < (long long((l.second).size())); ++i) {
      long long c0 = l.second[i].first, c1 = l.second[i].second;
      if (c0 <= v1) {
        v1 = c1;
      } else {
        iv.push_back({v0, v1});
        v0 = c0;
        v1 = c1;
      }
    }
    iv.push_back({v0, v1});
    intervals.push_back(iv);
  }
}
bool passable(const vector<pair<long long, long long>> &intervals,
              long long vmin, long long vmax) {
  long long LARGE = 10000;
  auto it = upper_bound((intervals).begin(), (intervals).end(),
                        pair<long long, long long>(vmin, LARGE));
  if (it == intervals.begin()) {
    return true;
  }
  it--;
  if (it->second >= vmax) {
    return false;
  }
  return true;
}
int main(int argc, char *argv[]) {
  long long N, M, i;
  cin >> N >> M;
  vector<long long> A(N), B(N), C(N), D(M), E(M), F(M);
  for (i = (0); i < (N); ++i) {
    cin >> A[i] >> B[i] >> C[i];
  }
  for (i = (0); i < (M); ++i) {
    cin >> D[i] >> E[i] >> F[i];
  }
  vector<long long> xs, ys;
  vector<vector<pair<long long, long long>>> x_intervals, y_intervals;
  parse_lines(C, A, B, xs, x_intervals);
  parse_lines(D, E, F, ys, y_intervals);
  if (N == 0 || M == 0) {
    cout << "INF" << endl;
    return 0;
  }
  long long NX = long long((xs).size()), NY = long long((ys).size());
  long long x0 = lower_bound((xs).begin(), (xs).end(), 0LL) - xs.begin();
  long long y0 = lower_bound((ys).begin(), (ys).end(), 0LL) - ys.begin();
  pair<long long, long long> p0(x0, y0);
  stack<pair<long long, long long>> st;
  st.push(p0);
  long long ans = 0;
  vector<vector<long long>> visited(NX + 1, vector<long long>(NY + 1, 0));
  visited[x0][y0] = 1;
  while (!st.empty()) {
    pair<long long, long long> cur = st.top();
    st.pop();
    if (cur.first == 0 || cur.first == NX || cur.second == 0 ||
        cur.second == NY) {
      cout << "INF" << endl;
      return 0;
    }
    long long xmin = xs[cur.first - 1], xmax = xs[cur.first];
    long long ymin = ys[cur.second - 1], ymax = ys[cur.second];
    ans += (xmax - xmin) * (ymax - ymin) / 4;
    if (passable(x_intervals[cur.first - 1], ymin, ymax) &&
        visited[cur.first - 1][cur.second] == 0) {
      st.push(pair<long long, long long>(cur.first - 1, cur.second));
      visited[cur.first - 1][cur.second] = 1;
    }
    if (passable(x_intervals[cur.first], ymin, ymax) &&
        visited[cur.first + 1][cur.second] == 0) {
      st.push(pair<long long, long long>(cur.first + 1, cur.second));
      visited[cur.first + 1][cur.second] = 1;
    }
    if (passable(y_intervals[cur.second - 1], xmin, xmax) &&
        visited[cur.first][cur.second - 1] == 0) {
      st.push(pair<long long, long long>(cur.first, cur.second - 1));
      visited[cur.first][cur.second - 1] = 1;
    }
    if (passable(y_intervals[cur.second], xmin, xmax) &&
        visited[cur.first][cur.second + 1] == 0) {
      st.push(pair<long long, long long>(cur.first, cur.second + 1));
      visited[cur.first][cur.second + 1] = 1;
    }
  }
  cout << ans << endl;
  return 0;
}
