// #define _GLIBCXX_DEBUG
// #define _LIBCPP_DEBUG 0

#include <iostream>
#include <iomanip>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <array>
#include <stack>
#include <tuple>
#include <string>
#include <algorithm>
#include <functional> // greater など
#include <cmath>      // abs など
#include <numeric>    // accumulate, gcd など
#include <cassert>    // assert
#include <stdexcept>
#include <bitset>
using namespace std;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, a, b) for (int i = (a); i < (int)(b); i++)
typedef long long ll;

//////////////// //////////////// //////////////// //////////////// ////////////////
//////////////// //////////////// //////////////// //////////////// ////////////////

constexpr int x_infty = 1000'000'000 + 1;

vector<int> dx = {1, 0, -1, 0}, dy = {0, 1, 0, -1};

int main()
{
    // 高速な入出力
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << setprecision(15); // 浮動小数の表示の精度

    int n, m;
    cin >> n >> m;
    vector<int> x_s = {-x_infty, -1, 0, 1, x_infty}, y_s = {-x_infty, -1, 0, 1, x_infty};
    vector<int> vert_x1(n), vert_x2(n), vert_y(n);
    rep(i, n)
    {
        cin >> vert_x1[i] >> vert_x2[i] >> vert_y[i];
        x_s.push_back(vert_x1[i]);
        x_s.push_back(vert_x2[i]);
        y_s.push_back(vert_y[i]);
    }
    vector<int> hori_x(m), hori_y1(m), hori_y2(m);
    rep(k, m)
    {
        cin >> hori_x[k] >> hori_y1[k] >> hori_y2[k];
        x_s.push_back(hori_x[k]);
        y_s.push_back(hori_y1[k]);
        y_s.push_back(hori_y2[k]);
    }
    sort(x_s.begin(), x_s.end());
    sort(y_s.begin(), y_s.end());
    x_s.erase(unique(x_s.begin(), x_s.end()), x_s.end());
    y_s.erase(unique(y_s.begin(), y_s.end()), y_s.end());

    // (x_cmp,y_cmp) を左上に持つ長方形も (x_cmp,y_cmp) と書く
    // is_wall[x_cmp][y_cmp][i] = (x_cmp,y_cmp) to (x_cmp+dx[i],y_cmp+dy[i]) が壁か?
    vector<vector<vector<bool>>> is_wall(x_s.size() - 1, vector<vector<bool>>(y_s.size() - 1, vector<bool>(4, false)));
    rep(i, n)
    {
        int x1_cmp = lower_bound(x_s.begin(), x_s.end(), vert_x1[i]) - x_s.begin();
        int x2_cmp = lower_bound(x_s.begin(), x_s.end(), vert_x2[i]) - x_s.begin();
        int y_cmp = lower_bound(y_s.begin(), y_s.end(), vert_y[i]) - y_s.begin();
        for (int x_cmp = x1_cmp; x_cmp < x2_cmp; x_cmp++)
        {
            is_wall[x_cmp][y_cmp - 1][1] = is_wall[x_cmp][y_cmp][3] = true;
        }
    }
    rep(k, m)
    {
        int x_cmp = lower_bound(x_s.begin(), x_s.end(), hori_x[k]) - x_s.begin();
        int y1_cmp = lower_bound(y_s.begin(), y_s.end(), hori_y1[k]) - y_s.begin();
        int y2_cmp = lower_bound(y_s.begin(), y_s.end(), hori_y2[k]) - y_s.begin();
        for (int y_cmp = y1_cmp; y_cmp < y2_cmp; y_cmp++)
        {
            is_wall[x_cmp - 1][y_cmp][0] = is_wall[x_cmp][y_cmp][2] = true;
        }
    }

    bool is_infty = false;
    ll ans = 0;
    vector<vector<bool>> used(x_s.size() - 1, vector<bool>(y_s.size() - 1, false));

    int x0 = lower_bound(x_s.begin(), x_s.end(), 0) - x_s.begin();
    int y0 = lower_bound(y_s.begin(), y_s.end(), 0) - y_s.begin();
    auto bfs = [&](int x_cmp_0, int y_cmp_0)
    {
        queue<int> x_cmps, y_cmps;
        used[x_cmp_0][y_cmp_0] = true;
        x_cmps.push(x_cmp_0);
        y_cmps.push(y_cmp_0);
        while (!x_cmps.empty()) {
            int x_cmp = x_cmps.front(); x_cmps.pop();
            int y_cmp = y_cmps.front(); y_cmps.pop();
            ans += ((ll)x_s[x_cmp + 1] - x_s[x_cmp]) * ((ll)y_s[y_cmp + 1] - y_s[y_cmp]);
            rep(i, 4)
            {
                if (is_wall[x_cmp][y_cmp][i])
                {
                    continue;
                }
                int x_cmp_new = x_cmp + dx[i];
                int y_cmp_new = y_cmp + dy[i];
                if (used[x_cmp_new][y_cmp_new])
                {
                    continue;
                }
                used[x_cmp_new][y_cmp_new] = true;
                if (x_cmp_new == 0 || x_cmp_new + 2 == (int)x_s.size() || y_cmp_new == 0 || y_cmp_new + 2 == (int)y_s.size())
                {
                    is_infty = true;
                    return;
                }
                x_cmps.push(x_cmp_new);
                y_cmps.push(y_cmp_new);
            }
        }
    };
    bfs(x0, y0);
    if (is_infty)
    {
        cout << "INF\n";
    }
    else
    {
        cout << ans << '\n';
    }

    return 0;
}


Measured memory_bytes: 639532