#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
using u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
using i8 = int8_t;
using i32 = int32_t;
using i64 = int64_t;
constexpr char newl = '\n';
constexpr double eps = 1e-10;
template <typename T1, typename T2>
inline void chmin(T1& a, T2 b) {
  if (a > b) a = b;
}
template <typename T1, typename T2>
inline void chmax(T1& a, T2 b) {
  if (a < b) a = b;
}
template <class T>
void Print(vector<T> v) {
  for (int i = (0); i < (v.size()); i++) {
    cout << v[i] << ' ';
  }
  cout << newl;
}
signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);
  int N, M;
  cin >> N >> M;
  struct LSS {
    int p;
    vector<pair<int, int>> s;
    LSS(int p = 0) : p(p) {}
    static bool leftCmp(const pair<int, int>& l, const pair<int, int>& r) {
      return l.first < r.first;
    }
    void Add(int start, int end) {
      pair<int, int> e = {start, end};
      int x = lower_bound(s.begin(), s.end(), e, leftCmp) - s.begin();
      int erasex, erasecnt = 0;
      if (x > 0 && s[x - 1].second >= e.first) {
        e.first = s[x - 1].first;
        chmax(e.second, s[x - 1].second);
        erasecnt++;
        erasex = x - 1;
      }
      while (x < s.size() && s[x].first <= e.second) {
        chmax(e.second, s[x].second);
        if (!erasecnt) erasex = x;
        erasecnt++;
        x++;
      }
      if (erasecnt) {
        s.erase(s.begin() + erasex, s.begin() + erasex + erasecnt);
        s.insert(s.begin() + erasex, e);
      } else {
        s.insert(s.begin() + x, e);
      }
    }
    bool hitCheck(int start, int end) {
      pair<int, int> e = {start + 1, end};
      int x = lower_bound(s.begin(), s.end(), e, leftCmp) - s.begin();
      if (--x < 0) return false;
      if (s[x].first <= start && end <= s[x].second) {
        return true;
      }
      return false;
    }
  };
  struct LS {
    int p, s, e;
    LS(int p = 0, int s = 0, int e = 0) : p(p), s(s), e(e) {}
  };
  auto lsCmp = [](const LS& l, const LS& r) { return l.p < r.p; };
  vector<LS> vls(N), hls(M);
  for (int i = (0); i < (N); i++) {
    cin >> vls[i].s >> vls[i].e >> vls[i].p;
  }
  for (int i = (0); i < (M); i++) {
    cin >> hls[i].p >> hls[i].s >> hls[i].e;
  }
  i64 result = 0;
  if (M > 1 && N > 1) {
    sort(hls.begin(), hls.end(), lsCmp);
    sort(vls.begin(), vls.end(), lsCmp);
    vector<LSS> vs, hs;
    auto ls2lss = [](vector<LSS>& lss, const vector<LS>& ls) {
      for (int i = (0); i < (ls.size()); i++) {
        if (lss.size() == 0 || ls[i].p != lss.back().p) {
          lss.emplace_back(ls[i].p);
        }
        lss.back().Add(ls[i].s, ls[i].e);
      }
    };
    ls2lss(vs, vls);
    ls2lss(hs, hls);
    auto lssCmp = [](const LSS& l, const LSS& r) { return l.p < r.p; };
    int mx = lower_bound(hs.begin(), hs.end(), LSS(0), lssCmp) - hs.begin();
    int my = lower_bound(vs.begin(), vs.end(), LSS(0), lssCmp) - vs.begin();
    vector<vector<bool>> vis(M - 1, vector<bool>(N - 1, false));
    queue<pair<int, int>> qu;
    qu.emplace(mx, my);
    while (qu.size()) {
      int x, y;
      tie(x, y) = qu.front();
      qu.pop();
      int px = x - 1, py = y - 1;
      if (px < 0 || py < 0 || x > vs.size() - 1 || y > hs.size() - 1) {
        result = 0;
        break;
      }
      if (vis[py][px]) continue;
      vis[py][px] = true;
      result += ((i64)vs[x].p - vs[px].p) * ((i64)hs[y].p - hs[py].p);
      if (!hs[py].hitCheck(vs[px].p, vs[x].p)) qu.emplace(x, y - 1);
      if (!vs[px].hitCheck(hs[py].p, hs[y].p)) qu.emplace(x - 1, y);
      if (!hs[y].hitCheck(vs[px].p, vs[x].p)) qu.emplace(x, y + 1);
      if (!vs[x].hitCheck(hs[py].p, hs[y].p)) qu.emplace(x + 1, y);
    }
  }
  if (result == 0)
    cout << "INF";
  else
    cout << result;
}
