#include <bits/stdc++.h>

using namespace std;
using ll = long long;
using vl = vector<ll>;
using vvl = vector<vl>;
using pll = pair<ll, ll>;

const ll oo = 0x3f3f3f3f3f3f3f3fLL;
const double eps = 1e-9;

#define sz(c) ll((c).size())
#define all(c) begin(c), end(c)
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define eb emplace_back
#define xx first
#define yy second
#define FOR(i, a, b) for (ll i = (a); i < (b); i++)
#define FORD(i, a, b) for (ll i = ll(b) - 1; i >= (a); i--)
#define TR(X)                                                  \
    ({                                                         \
        if (1) cerr << "TR: " << (#X) << " = " << (X) << endl; \
    })
#define LL(name) \
    ll name;     \
    cin >> name;
#define VL(name, num) \
    vl name(num);     \
    FOR(INPUT_VL_I, 0, num) { cin >> name[INPUT_VL_I]; }

const vl dx = {0, 0, 1, -1};
const vl dy = {1, -1, 0, 0};

const ll DOWN = 1 << 0;
const ll UP = 1 << 1;
const ll RIGHT = 1 << 2;
const ll LEFT = 1 << 3;

int main() {
    cin.sync_with_stdio(0);
    LL(N);
    LL(M);

    vl As(N), Bs(N), Cs(N);
    vl Xs, Ys;

    Xs.pb(0);
    Ys.pb(0);
    Xs.pb(oo);
    Xs.pb(-oo);
    Ys.pb(oo);
    Ys.pb(-oo);

    FOR(i, 0, N) {
        // From y = As[i] to Bs[i] on x = Cs[i]
        cin >> As[i] >> Bs[i] >> Cs[i];
        Ys.pb(As[i]);
        Ys.pb(Bs[i]);
        Xs.pb(Cs[i]);
    }

    vl Ds(M), Es(M), Fs(M);
    FOR(i, 0, M) {
        // From x = Es[i] to Fs[i] on y = Ds[i]
        cin >> Ds[i] >> Es[i] >> Fs[i];
        Xs.pb(Es[i]);
        Xs.pb(Fs[i]);
        Ys.pb(Ds[i]);
    }

    sort(all(Xs));
    Xs.erase(unique(all(Xs)), Xs.end());
    sort(all(Ys));
    Ys.erase(unique(all(Ys)), Ys.end());

    auto getX = [&Xs](int x) { return lower_bound(all(Xs), x) - Xs.begin(); };
    auto getY = [&Ys](int y) { return lower_bound(all(Ys), y) - Ys.begin(); };

    vvl grid(sz(Xs), vl(sz(Ys)));

    FOR(i, 0, N) {
        const ll fromY = getY(As[i]);
        const ll toY = getY(Bs[i]);
        const ll onX = getX(Cs[i]);

        FOR(y, fromY, toY) {
            grid[onX - 1][y] |= RIGHT;
            grid[onX][y] |= LEFT;
        }
    }
    FOR(i, 0, M) {
        const ll fromX = getX(Es[i]);
        const ll toX = getX(Fs[i]);
        const ll onY = getY(Ds[i]);

        FOR(x, fromX, toX) {
            grid[x][onY] |= UP;
            grid[x][onY - 1] |= DOWN;
        }
    }

    queue<pll> todo;
    todo.emplace(getX(0), getY(0));
    vvl visited(sz(Xs), vl(sz(Ys)));
    visited[getX(0)][getY(0)] = true;
    while (sz(todo)) {
        const pll cur = todo.front();
        todo.pop();

        FOR(k, 0, 4) {
            if (grid[cur.xx][cur.yy] & (1ll << k)) {
                continue;
            }
            const ll nx = cur.xx + dx[k];
            const ll ny = cur.yy + dy[k];

            if (nx < 0 || ny < 0 || nx >= sz(Xs) || ny >= sz(Ys)) {
                continue;
            }

            if (visited[nx][ny]) {
                continue;
            }

            visited[nx][ny] = true;
            todo.emplace(nx, ny);
        }
    }

    ll ans = 0;
    FOR(x, 0, sz(Xs)) {
        FOR(y, 0, sz(Ys)) {
            if (visited[x][y]) {
                if (x == 0 || y == 0 || x == sz(Xs) - 1 || y == sz(Ys) - 1) {
                    ans = oo;
                    goto end;
                }
                ans += (Xs[x + 1] - Xs[x]) * (Ys[y + 1] - Ys[y]);
            }
        }
    }

end:
    if (ans == oo) cout << "INF" << endl;
    else cout << ans << endl;
}  // cin.tie(0) bei schnellem Wechseln


Measured memory_bytes: 144440