Problem p02680 (C++) — buggy submission, verdict: Time Limit Exceeded

#pragma region Macros
#pragma GCC optimize("O3")

#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define rep2(i, a, b) for (ll i = a; i <= b; ++i)
#define rep(i, n) for (ll i = 0; i < n; ++i)
#define rep3(i, a, b) for (ll i = a; i >= b; --i)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pb push_back
#define eb emplace_back
#define vi vector<int>
#define vec vector<int>
#define vll vector<ll>
#define vpi vector<pii>
#define vpll vector<pll>
#define overload2(_1, _2, name, ...) name
#define vv(a, b) vector<vector<int>>(a, vector<int>(b))
#define vv2(a, b, c) vector<vector<int>>(a, vector<int>(b, c))
#define vvl(a, b) vector<vector<ll>>(a, vector<ll>(b))
#define vvl2(a, b, c) vector<vector<ll>>(a, vector<ll>(b, c))
#define vvv(a, b, c) vector<vv(b, c)>(a)
#define vvv2(a, b, c, d) vector<vv(b, c, d)>(a)
#define vvvl(a, b, c) vector<vvl(b, c)>(a)
#define vvvl2(a, b, c, d) vector<vvl(b, c, d)>(a)
#define fi first
#define se second
#define all(c) begin(c), end(c)
#define ios ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define lb(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define ub(c, x) distance((c).begin(), upper_bound(all(c), (x)))
using namespace std;
template <class T> using pq = priority_queue<T>;
template <class T> using pqg = priority_queue<T, vector<T>, greater<T>>;
#define INT(...)                                                               \\
  int __VA_ARGS__;                                                             \\
  IN(__VA_ARGS__)
#define LL(...)                                                                \\
  ll __VA_ARGS__;                                                              \\
  IN(__VA_ARGS__)
#define ULL(...)                                                               \\
  ull __VA_ARGS__;                                                             \\
  IN(__VA_ARGS__)
#define STR(...)                                                               \\
  string __VA_ARGS__;                                                          \\
  IN(__VA_ARGS__)
#define CHR(...)                                                               \\
  char __VA_ARGS__;                                                            \\
  IN(__VA_ARGS__)
#define DBL(...)                                                               \\
  double __VA_ARGS__;                                                          \\
  IN(__VA_ARGS__)
#define LD(...)                                                                \\
  ld __VA_ARGS__;                                                              \\
  IN(__VA_ARGS__)
#define VEC(type, name, size)                                                  \\
  vector<type> name(size);                                                     \\
  IN(name)
#define VV(type, name, h, w)                                                   \\
  vector<vector<type>> name(h, vector<type>(w));                               \\
  IN(name)
int scan() { return getchar(); }
void scan(int &a) { cin >> a; }
void scan(long long &a) { cin >> a; }
void scan(char &a) { cin >> a; }
void scan(double &a) { cin >> a; }
void scan(long double &a) { cin >> a; }
void scan(char a[]) { scanf("%s", a); }
void scan(string &a) { cin >> a; }
template <class T> void scan(vector<T> &);
template <class T, size_t size> void scan(array<T, size> &);
template <class T, class L> void scan(pair<T, L> &);
template <class T, size_t size> void scan(T (&)[size]);
template <class T> void scan(vector<T> &a) {
  for (auto &i : a)
    scan(i);
}
template <class T> void scan(deque<T> &a) {
  for (auto &i : a)
    scan(i);
}
template <class T, size_t size> void scan(array<T, size> &a) {
  for (auto &i : a)
    scan(i);
}
template <class T, class L> void scan(pair<T, L> &p) {
  scan(p.first);
  scan(p.second);
}
template <class T, size_t size> void scan(T (&a)[size]) {
  for (auto &i : a)
    scan(i);
}
template <class T> void scan(T &a) { cin >> a; }
void IN() {}
template <class Head, class... Tail> void IN(Head &head, Tail &...tail) {
  scan(head);
  IN(tail...);
}
string stin() {
  string s;
  cin >> s;
  return s;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
vi iota(int n) {
  vi a(n);
  iota(all(a), 0);
  return a;
}
template <class T> void UNIQUE(vector<T> &x) {
  sort(all(x));
  x.erase(unique(all(x)), x.end());
}
int in() {
  int x;
  cin >> x;
  return x;
}
ll lin() {
  unsigned long long x;
  cin >> x;
  return x;
}
void print() { putchar(' '); }
void print(bool a) { cout << a; }
void print(int a) { cout << a; }
void print(long long a) { cout << a; }
void print(char a) { cout << a; }
void print(string &a) { cout << a; }
void print(double a) { cout << a; }
template <class T> void print(const vector<T> &);
template <class T, size_t size> void print(const array<T, size> &);
template <class T, class L> void print(const pair<T, L> &p);
template <class T, size_t size> void print(const T (&)[size]);
template <class T> void print(const vector<T> &a) {
  if (a.empty())
    return;
  print(a[0]);
  for (auto i = a.begin(); ++i != a.end();) {
    cout << " ";
    print(*i);
  }
  cout << endl;
}
template <class T> void print(const deque<T> &a) {
  if (a.empty())
    return;
  print(a[0]);
  for (auto i = a.begin(); ++i != a.end();) {
    cout << " ";
    print(*i);
  }
}
template <class T, size_t size> void print(const array<T, size> &a) {
  print(a[0]);
  for (auto i = a.begin(); ++i != a.end();) {
    cout << " ";
    print(*i);
  }
}
template <class T, class L> void print(const pair<T, L> &p) {
  cout << '(';
  print(p.first);
  cout << ",";
  print(p.second);
  cout << ')';
}
template <class T, size_t size> void print(const T (&a)[size]) {
  print(a[0]);
  for (auto i = a; ++i != end(a);) {
    cout << " ";
    print(*i);
  }
}
template <class T> void print(const T &a) { cout << a; }
int out() {
  putchar('\\n');
  return 0;
}
template <class T> int out(const T &t) {
  print(t);
  putchar('\\n');
  return 0;
}
template <class Head, class... Tail>
int out(const Head &head, const Tail &...tail) {
  print(head);
  putchar(' ');
  out(tail...);
  return 0;
}
ll gcd(ll a, ll b) {
  while (b) {
    ll c = b;
    b = a % b;
    a = c;
  }
  return a;
}
ll lcm(ll a, ll b) {
  if (!a || !b)
    return 0;
  return a * b / gcd(a, b);
}
vector<pll> factor(ll x) {
  vector<pll> ans;
  for (ll i = 2; i * i <= x; i++)
    if (x % i == 0) {
      ans.push_back({i, 1});
      while ((x /= i) % i == 0)
        ans.back().second++;
    }
  if (x != 1)
    ans.push_back({x, 1});
  return ans;
}
vector<int> divisor(int x) {
  vector<int> ans;
  for (int i = 1; i * i <= x; i++)
    if (x % i == 0) {
      ans.pb(i);
      if (i * i != x)
        ans.pb(x / i);
    }
  return ans;
}
int popcount(ll x) { return __builtin_popcountll(x); }
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int rnd(int n) { return uniform_int_distribution<int>(0, n)(rng); }
#define endl '\\n'

#ifdef _LOCAL
#undef endl
#define debug(x)                                                               \\
  cout << #x << ": ";                                                          \\
  print(x);                                                                    \\
  cout << endl;
void err() {}
template <class T> void err(const T &t) {
  print(t);
  cout << " ";
}
template <class Head, class... Tail>
void err(const Head &head, const Tail &...tail) {
  print(head);
  putchar(' ');
  out(tail...);
}
#else
#define debug(x)
template <class... T> void err(const T &...) {}
#endif
#pragma endregion

template <typename Monoid> struct SegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;

  int sz;
  vector<Monoid> seg;

  const F f;
  const Monoid M1;

  SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {
    sz = 1;
    while (sz < n)
      sz <<= 1;
    seg.assign(2 * sz, M1);
  }

  void set(int k, const Monoid &x) { seg[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] += x;
    while (k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  Monoid query(int a, int b) {
    Monoid L = M1, R = M1;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1)
        L = f(L, seg[a++]);
      if (b & 1)
        R = f(seg[--b], R);
    }
    return f(L, R);
  }

  Monoid operator[](const int &k) const { return seg[k + sz]; }

  template <typename C>
  int find_subtree(int a, const C &check, Monoid &M, bool type) {
    while (a < sz) {
      Monoid nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]);
      if (check(nxt))
        a = 2 * a + type;
      else
        M = nxt, a = 2 * a + 1 - type;
    }
    return a - sz;
  }

  template <typename C> int find_first(int a, const C &check) {
    Monoid L = M1;
    if (a <= 0) {
      if (check(f(L, seg[1])))
        return find_subtree(1, check, L, false);
      return -1;
    }
    int b = sz;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) {
        Monoid nxt = f(L, seg[a]);
        if (check(nxt))
          return find_subtree(a, check, L, false);
        L = nxt;
        ++a;
      }
    }
    return -1;
  }

  template <typename C> int find_last(int b, const C &check) {
    Monoid R = M1;
    if (b >= sz) {
      if (check(f(seg[1], R)))
        return find_subtree(1, check, R, true);
      return -1;
    }
    int a = sz;
    for (b += sz; a < b; a >>= 1, b >>= 1) {
      if (b & 1) {
        Monoid nxt = f(seg[--b], R);
        if (check(nxt))
          return find_subtree(b, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }
  void print(int n) {
    for (int i = 0; i < n; i++) {
      cerr << seg[i + sz] << " ";
    }
    cerr << endl;
  }
};
const ll MOD = 1e9 + 7;
const int N = 1100000;

template <ll Modulus> class modint {
  using u64 = ll;

public:
  u64 a;

  constexpr modint(const u64 x = 0) noexcept
      : a(((x % Modulus) + Modulus) % Modulus) {}
  constexpr u64 &value() noexcept { return a; }
  constexpr const u64 &value() const noexcept { return a; }
  constexpr modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if (a >= Modulus) {
      a -= Modulus;
    }
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if (a < rhs.a) {
      a += Modulus;
    }
    a -= rhs.a;
    return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
    a = a * rhs.a % Modulus;
    return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
    u64 exp = Modulus - 2;
    while (exp) {
      if (exp % 2) {
        *this *= rhs;
      }
      rhs *= rhs;
      exp /= 2;
    }
    return *this;
  }
};

#define mint modint<MOD>
mint inv[N], comb[N], prd[N], invprd[N];
void calc_inv() {
  inv[1] = 1;
  rep2(i, 2, N - 1) { inv[i] = inv[MOD % i] * (-MOD / i); }
  return;
}
void calc_product() {
  prd[0] = prd[1] = 1;
  invprd[0] = invprd[1] = 1;
  rep2(i, 2, N - 1) {
    prd[i] = prd[i - 1] * i;
    invprd[i] = inv[i] * invprd[i - 1];
  }
  return;
}
mint cmb(int a, int b) {
  if (a < b)
    return 0;
  if (a < 0 || b < 0)
    return 0;
  return {prd[a] * invprd[b] * invprd[a - b]};
}
mint modpow(mint x, ll n) {
  if (n == 0)
    return 1;
  mint res = modpow(x * x, n / 2);
  if (n & 1)
    res = res * x;
  return res;
}
void calc() {
  calc_inv();
  calc_product();
}
using vmint = vector<mint>;
ostream &operator<<(ostream &os, mint a) {
  os << a.a;
  return os;
}
struct UnionFind {
  vector<int> data;
  vector<ll> size;
  UnionFind(int sz) {
    data.assign(sz, -1);
    size.resize(sz);
  }

  bool unite(int x, int y) {
    x = find(x), y = find(y);
    if (x == y)
      return (false);
    if (data[x] > data[y])
      swap(x, y);
    data[x] += data[y];
    data[y] = x;
    size[x] += size[y];
    chmin(size[x], (ll)4e18 + 1);
    return (true);
  }

  int find(int k) {
    if (data[k] < 0)
      return (k);
    return (data[k] = find(data[k]));
  }

  ll SIZE(int k) { return (size[find(k)]); }
};
vector<set<int>> grid_graph(int n, int m) {
  vector<set<int>> res(n * m);
  int d[5] = {0, 1, 0, -1, 0};
  rep(i, n) rep(j, m) {
    rep(t, 4) {
      if (0 <= i + d[t] and 0 <= j + d[t + 1] and i + d[t] < n and
          j + d[t + 1] < m) {
        res[i * m + j].emplace((i + d[t]) * m + j + d[t + 1]);
      }
    }
  }
  return res;
}

template <typename T> vector<T> Onedim(vector<vector<T>> &v) {
  vector<T> res;
  for (auto &w : v)
    for (auto &e : w)
      res.emplace_back(e);
  return res;
}
signed main() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  cout << fixed << setprecision(15);
  INT(n, m);
  ll INF = 2e9;
  vector<ll> x{INF}, y{INF};
  vector<ll> a, b, c, d, e, ff;
  rep(i, n) {
    a.eb(in()), b.eb(in()), c.eb(in());
    x.pb(c.back());
  }
  rep(i, m) {
    ff.eb(in());
    d.eb(in()), e.eb(in());
    y.eb(ff.back());
  }
  UNIQUE(x), UNIQUE(y);
  auto g = grid_graph(x.size(), y.size());
  auto f = [&](int s, int t) { return s * y.size() + t; };
  UnionFind uf(x.size() * y.size());
  int N = x.size() * y.size();
  rep(i, N) { uf.size[i] = 1; }
  ll pre = -INF;
  rep(i, x.size()) {
    rep(j, y.size()) { uf.size[f(i, j)] *= (x[i] - pre); }
    pre = x[i];
  }

  pre = -INF;
  rep(j, y.size()) {
    rep(i, x.size()) { uf.size[f(i, j)] *= (y[j] - pre); }
    pre = y[j];
  }
  ll LINF = 4e18;
  rep(i, x.size()) uf.size[f(i, 0)] = uf.size[f(i, y.size() - 1)] = LINF + 1;
  rep(j, y.size()) uf.size[f(0, j)] = uf.size[f(x.size() - 1, j)] = LINF + 1;
  rep(i, n) {
    int X = lb(x, c[i]);
    if (a[i] > b[i])
      swap(a[i], b[i]);
    int l = lb(y, a[i]), r = ub(y, b[i]);
    rep2(j, l + 1, r - 1) {
      g[f(X, j)].erase(f(X + 1, j));
      g[f(X + 1, j)].erase(f(X, j));
    }
  }
  rep(i, m) {
    int Y = lb(y, ff[i]);
    if (d[i] > e[i])
      swap(d[i], e[i]);
    int l = lb(x, d[i]), r = ub(x, e[i]);
    rep2(j, l + 1, r - 1) {
      g[f(j, Y)].erase(f(j, Y + 1));
      g[f(j, Y + 1)].erase(f(j, Y));
    }
  }
  rep(i, N) {
    for (auto e : g[i]) {
      uf.unite(i, e);
    }
  }
  int t = lb(x, 0), s = lb(y, 0);
  ll ans = uf.SIZE(f(t, s));
  if (ans > LINF)
    cout << "INF\\n";
  else
    cout << uf.SIZE(f(t, s)) << endl;
}

Error: TLE

Fixed submission:

#pragma region Macros
#pragma GCC optimize("O3")

#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define rep2(i, a, b) for (ll i = a; i <= b; ++i)
#define rep(i, n) for (ll i = 0; i < n; ++i)
#define rep3(i, a, b) for (ll i = a; i >= b; --i)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pb push_back
#define eb emplace_back
#define vi vector<int>
#define vec vector<int>
#define vll vector<ll>
#define vpi vector<pii>
#define vpll vector<pll>
#define overload2(_1, _2, name, ...) name
#define vv(a, b) vector<vector<int>>(a, vector<int>(b))
#define vv2(a, b, c) vector<vector<int>>(a, vector<int>(b, c))
#define vvl(a, b) vector<vector<ll>>(a, vector<ll>(b))
#define vvl2(a, b, c) vector<vector<ll>>(a, vector<ll>(b, c))
#define vvv(a, b, c) vector<vv(b, c)>(a)
#define vvv2(a, b, c, d) vector<vv(b, c, d)>(a)
#define vvvl(a, b, c) vector<vvl(b, c)>(a)
#define vvvl2(a, b, c, d) vector<vvl(b, c, d)>(a)
#define fi first
#define se second
#define all(c) begin(c), end(c)
#define ios ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define lb(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define ub(c, x) distance((c).begin(), upper_bound(all(c), (x)))
using namespace std;
template <class T> using pq = priority_queue<T>;
template <class T> using pqg = priority_queue<T, vector<T>, greater<T>>;
#define INT(...)                                                               \\
  int __VA_ARGS__;                                                             \\
  IN(__VA_ARGS__)
#define LL(...)                                                                \\
  ll __VA_ARGS__;                                                              \\
  IN(__VA_ARGS__)
#define ULL(...)                                                               \\
  ull __VA_ARGS__;                                                             \\
  IN(__VA_ARGS__)
#define STR(...)                                                               \\
  string __VA_ARGS__;                                                          \\
  IN(__VA_ARGS__)
#define CHR(...)                                                               \\
  char __VA_ARGS__;                                                            \\
  IN(__VA_ARGS__)
#define DBL(...)                                                               \\
  double __VA_ARGS__;                                                          \\
  IN(__VA_ARGS__)
#define LD(...)                                                                \\
  ld __VA_ARGS__;                                                              \\
  IN(__VA_ARGS__)
#define VEC(type, name, size)                                                  \\
  vector<type> name(size);                                                     \\
  IN(name)
#define VV(type, name, h, w)                                                   \\
  vector<vector<type>> name(h, vector<type>(w));                               \\
  IN(name)
int scan() { return getchar(); }
void scan(int &a) { cin >> a; }
void scan(long long &a) { cin >> a; }
void scan(char &a) { cin >> a; }
void scan(double &a) { cin >> a; }
void scan(long double &a) { cin >> a; }
void scan(char a[]) { scanf("%s", a); }
void scan(string &a) { cin >> a; }
template <class T> void scan(vector<T> &);
template <class T, size_t size> void scan(array<T, size> &);
template <class T, class L> void scan(pair<T, L> &);
template <class T, size_t size> void scan(T (&)[size]);
template <class T> void scan(vector<T> &a) {
  for (auto &i : a)
    scan(i);
}
template <class T> void scan(deque<T> &a) {
  for (auto &i : a)
    scan(i);
}
template <class T, size_t size> void scan(array<T, size> &a) {
  for (auto &i : a)
    scan(i);
}
template <class T, class L> void scan(pair<T, L> &p) {
  scan(p.first);
  scan(p.second);
}
template <class T, size_t size> void scan(T (&a)[size]) {
  for (auto &i : a)
    scan(i);
}
template <class T> void scan(T &a) { cin >> a; }
void IN() {}
template <class Head, class... Tail> void IN(Head &head, Tail &...tail) {
  scan(head);
  IN(tail...);
}
string stin() {
  string s;
  cin >> s;
  return s;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
vi iota(int n) {
  vi a(n);
  iota(all(a), 0);
  return a;
}
template <class T> void UNIQUE(vector<T> &x) {
  sort(all(x));
  x.erase(unique(all(x)), x.end());
}
int in() {
  int x;
  cin >> x;
  return x;
}
ll lin() {
  unsigned long long x;
  cin >> x;
  return x;
}
void print() { putchar(' '); }
void print(bool a) { cout << a; }
void print(int a) { cout << a; }
void print(long long a) { cout << a; }
void print(char a) { cout << a; }
void print(string &a) { cout << a; }
void print(double a) { cout << a; }
template <class T> void print(const vector<T> &);
template <class T, size_t size> void print(const array<T, size> &);
template <class T, class L> void print(const pair<T, L> &p);
template <class T, size_t size> void print(const T (&)[size]);
template <class T> void print(const vector<T> &a) {
  if (a.empty())
    return;
  print(a[0]);
  for (auto i = a.begin(); ++i != a.end();) {
    cout << " ";
    print(*i);
  }
  cout << endl;
}
template <class T> void print(const deque<T> &a) {
  if (a.empty())
    return;
  print(a[0]);
  for (auto i = a.begin(); ++i != a.end();) {
    cout << " ";
    print(*i);
  }
}
template <class T, size_t size> void print(const array<T, size> &a) {
  print(a[0]);
  for (auto i = a.begin(); ++i != a.end();) {
    cout << " ";
    print(*i);
  }
}
template <class T, class L> void print(const pair<T, L> &p) {
  cout << '(';
  print(p.first);
  cout << ",";
  print(p.second);
  cout << ')';
}
template <class T, size_t size> void print(const T (&a)[size]) {
  print(a[0]);
  for (auto i = a; ++i != end(a);) {
    cout << " ";
    print(*i);
  }
}
template <class T> void print(const T &a) { cout << a; }
int out() {
  putchar('\\n');
  return 0;
}
template <class T> int out(const T &t) {
  print(t);
  putchar('\\n');
  return 0;
}
template <class Head, class... Tail>
int out(const Head &head, const Tail &...tail) {
  print(head);
  putchar(' ');
  out(tail...);
  return 0;
}
ll gcd(ll a, ll b) {
  while (b) {
    ll c = b;
    b = a % b;
    a = c;
  }
  return a;
}
ll lcm(ll a, ll b) {
  if (!a || !b)
    return 0;
  return a * b / gcd(a, b);
}
vector<pll> factor(ll x) {
  vector<pll> ans;
  for (ll i = 2; i * i <= x; i++)
    if (x % i == 0) {
      ans.push_back({i, 1});
      while ((x /= i) % i == 0)
        ans.back().second++;
    }
  if (x != 1)
    ans.push_back({x, 1});
  return ans;
}
vector<int> divisor(int x) {
  vector<int> ans;
  for (int i = 1; i * i <= x; i++)
    if (x % i == 0) {
      ans.pb(i);
      if (i * i != x)
        ans.pb(x / i);
    }
  return ans;
}
int popcount(ll x) { return __builtin_popcountll(x); }
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int rnd(int n) { return uniform_int_distribution<int>(0, n)(rng); }
#define endl '\\n'

#ifdef _LOCAL
#undef endl
#define debug(x)                                                               \\
  cout << #x << ": ";                                                          \\
  print(x);                                                                    \\
  cout << endl;
void err() {}
template <class T> void err(const T &t) {
  print(t);
  cout << " ";
}
template <class Head, class... Tail>
void err(const Head &head, const Tail &...tail) {
  print(head);
  putchar(' ');
  out(tail...);
}
#else
#define debug(x)
template <class... T> void err(const T &...) {}
#endif
#pragma endregion

template <typename Monoid> struct SegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;

  int sz;
  vector<Monoid> seg;

  const F f;
  const Monoid M1;

  SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {
    sz = 1;
    while (sz < n)
      sz <<= 1;
    seg.assign(2 * sz, M1);
  }

  void set(int k, const Monoid &x) { seg[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] += x;
    while (k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  Monoid query(int a, int b) {
    Monoid L = M1, R = M1;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1)
        L = f(L, seg[a++]);
      if (b & 1)
        R = f(seg[--b], R);
    }
    return f(L, R);
  }

  Monoid operator[](const int &k) const { return seg[k + sz]; }

  template <typename C>
  int find_subtree(int a, const C &check, Monoid &M, bool type) {
    while (a < sz) {
      Monoid nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]);
      if (check(nxt))
        a = 2 * a + type;
      else
        M = nxt, a = 2 * a + 1 - type;
    }
    return a - sz;
  }

  template <typename C> int find_first(int a, const C &check) {
    Monoid L = M1;
    if (a <= 0) {
      if (check(f(L, seg[1])))
        return find_subtree(1, check, L, false);
      return -1;
    }
    int b = sz;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) {
        Monoid nxt = f(L, seg[a]);
        if (check(nxt))
          return find_subtree(a, check, L, false);
        L = nxt;
        ++a;
      }
    }
    return -1;
  }

  template <typename C> int find_last(int b, const C &check) {
    Monoid R = M1;
    if (b >= sz) {
      if (check(f(seg[1], R)))
        return find_subtree(1, check, R, true);
      return -1;
    }
    int a = sz;
    for (b += sz; a < b; a >>= 1, b >>= 1) {
      if (b & 1) {
        Monoid nxt = f(seg[--b], R);
        if (check(nxt))
          return find_subtree(b, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }
  void print(int n) {
    for (int i = 0; i < n; i++) {
      cerr << seg[i + sz] << " ";
    }
    cerr << endl;
  }
};
const ll MOD = 1e9 + 7;
const int N = 1100000;

template <ll Modulus> class modint {
  using u64 = ll;

public:
  u64 a;

  constexpr modint(const u64 x = 0) noexcept
      : a(((x % Modulus) + Modulus) % Modulus) {}
  constexpr u64 &value() noexcept { return a; }
  constexpr const u64 &value() const noexcept { return a; }
  constexpr modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if (a >= Modulus) {
      a -= Modulus;
    }
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if (a < rhs.a) {
      a += Modulus;
    }
    a -= rhs.a;
    return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
    a = a * rhs.a % Modulus;
    return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
    u64 exp = Modulus - 2;
    while (exp) {
      if (exp % 2) {
        *this *= rhs;
      }
      rhs *= rhs;
      exp /= 2;
    }
    return *this;
  }
};

#define mint modint<MOD>
mint inv[N], comb[N], prd[N], invprd[N];
void calc_inv() {
  inv[1] = 1;
  rep2(i, 2, N - 1) { inv[i] = inv[MOD % i] * (-MOD / i); }
  return;
}
void calc_product() {
  prd[0] = prd[1] = 1;
  invprd[0] = invprd[1] = 1;
  rep2(i, 2, N - 1) {
    prd[i] = prd[i - 1] * i;
    invprd[i] = inv[i] * invprd[i - 1];
  }
  return;
}
mint cmb(int a, int b) {
  if (a < b)
    return 0;
  if (a < 0 || b < 0)
    return 0;
  return {prd[a] * invprd[b] * invprd[a - b]};
}
mint modpow(mint x, ll n) {
  if (n == 0)
    return 1;
  mint res = modpow(x * x, n / 2);
  if (n & 1)
    res = res * x;
  return res;
}
void calc() {
  calc_inv();
  calc_product();
}
using vmint = vector<mint>;
ostream &operator<<(ostream &os, mint a) {
  os << a.a;
  return os;
}
struct UnionFind {
  vector<int> data;
  vector<ll> size;
  UnionFind(int sz) {
    data.assign(sz, -1);
    size.resize(sz);
  }

  bool unite(int x, int y) {
    x = find(x), y = find(y);
    if (x == y)
      return (false);
    if (data[x] > data[y])
      swap(x, y);
    data[x] += data[y];
    data[y] = x;
    size[x] += size[y];
    chmin(size[x], (ll)4e18 + 1);
    return (true);
  }

  int find(int k) {
    if (data[k] < 0)
      return (k);
    return (data[k] = find(data[k]));
  }

  ll SIZE(int k) { return (size[find(k)]); }
};
vector<set<int>> grid_graph(int n, int m) {
  vector<set<int>> res(n * m);
  int d[5] = {0, 1, 0, -1, 0};
  rep(i, n) rep(j, m) {
    rep(t, 4) {
      if (0 <= i + d[t] and 0 <= j + d[t + 1] and i + d[t] < n and
          j + d[t + 1] < m) {
        res[i * m + j].emplace((i + d[t]) * m + j + d[t + 1]);
      }
    }
  }
  return res;
}

template <typename T> vector<T> Onedim(vector<vector<T>> &v) {
  vector<T> res;
  for (auto &w : v)
    for (auto &e : w)
      res.emplace_back(e);
  return res;
}
signed main() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  cout << fixed << setprecision(15);
  INT(n, m);
  ll INF = 2e9;
  vector<ll> x{INF}, y{INF};
  vector<ll> a, b, c, d, e, ff;
  rep(i, n) {
    a.eb(in()), b.eb(in()), c.eb(in());
    x.pb(c.back());
    y.eb(a.back()), y.eb(b.back());
  }
  rep(i, m) {
    ff.eb(in());
    d.eb(in()), e.eb(in());
    x.eb(d.back()), x.eb(e.back());
    y.eb(ff.back());
  }
  UNIQUE(x), UNIQUE(y);
  auto g = grid_graph(x.size(), y.size());
  auto f = [&](int s, int t) { return s * y.size() + t; };
  UnionFind uf(x.size() * y.size());
  int N = x.size() * y.size();
  rep(i, N) { uf.size[i] = 1; }
  ll pre = -INF;
  rep(i, x.size()) {
    rep(j, y.size()) { uf.size[f(i, j)] *= (x[i] - pre); }
    pre = x[i];
  }

  pre = -INF;
  rep(j, y.size()) {
    rep(i, x.size()) { uf.size[f(i, j)] *= (y[j] - pre); }
    pre = y[j];
  }
  ll LINF = 4e18;
  rep(i, x.size()) uf.size[f(i, 0)] = uf.size[f(i, y.size() - 1)] = LINF + 1;
  rep(j, y.size()) uf.size[f(0, j)] = uf.size[f(x.size() - 1, j)] = LINF + 1;
  rep(i, n) {
    int X = lb(x, c[i]);
    int l = lb(y, a[i]), r = lb(y, b[i]);
    if (l > r)
      swap(l, r);
    rep2(j, l + 1, r) {
      g[f(X, j)].erase(f(X + 1, j));
      g[f(X + 1, j)].erase(f(X, j));
    }
  }
  rep(i, m) {
    int Y = lb(y, ff[i]);
    int l = lb(x, d[i]), r = lb(x, e[i]);
    if (l > r)
      swap(l, r);
    rep2(j, l + 1, r) {
      g[f(j, Y)].erase(f(j, Y + 1));
      g[f(j, Y + 1)].erase(f(j, Y));
    }
  }
  rep(i, N) {
    for (auto e : g[i]) {
      uf.unite(i, e);
    }
  }
  int t = lb(x, 0), s = lb(y, 0);
  ll ans = uf.SIZE(f(t, s));
  if (ans > LINF)
    cout << "INF\\n";
  else
    cout << uf.SIZE(f(t, s)) << endl;
}