#include <bits/stdc++.h>
using namespace std;

// one-based numbering
struct UnionFind {
    vector<int> data;
    // i: (data[i] < 0) -> group size, (data[i] > 0) -> parent;
    UnionFind(int n) {
        data.resize(n+1, -1);
    }
    int find(int x) {
        if(data[x] < 0) return x;
        else return data[x] = find(data[x]);
    }
    int size(int x) {
        return -data[find(x)];
    }
    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;
        return true;
    }
    bool same(int x, int y) {
        x = find(x); y = find(y);
        return x == y;
    }
};

set<int> V[9100000];

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    int N, M; cin >> N >> M;
    vector<long long> A(N), B(N), C(N), D(M), E(M), F(M);
    vector<long long> X, Y;

    for (int i = 0; i < N; i++) {
        cin >> A[i] >> B[i] >> C[i];
        X.emplace_back(A[i]);
        X.emplace_back(B[i]);
        Y.emplace_back(C[i]);
    }
    for (int i = 0; i < M; i++) {
        cin >> D[i] >> E[i] >> F[i];
        X.emplace_back(D[i]);
        Y.emplace_back(E[i]);
        Y.emplace_back(F[i]);
    }

    sort(X.begin(), X.end());
    X.erase(unique(X.begin(), X.end()), X.end());
    sort(Y.begin(), Y.end());
    Y.erase(unique(Y.begin(), Y.end()), Y.end());

    int Xs = X.size(), Ys = Y.size();
    auto encode = [&](int i, int j) { return i * (Ys+2) + j + 1; }; 

    for (int i = 0; i < N; i++) {
        int a = A[i], b = B[i], c = C[i];
        int xl = lower_bound(X.begin(), X.end(), a) - X.begin();
        int xr = lower_bound(X.begin(), X.end(), b) - X.begin();
        int y = lower_bound(Y.begin(), Y.end(), c) - Y.begin();
        for (int x = xl+1; x <= xr; x++) {
            V[encode(x, y)].emplace(encode(x, y+1));
        }
    }
    for (int i = 0; i < M; i++) {
        int d = D[i], e = E[i], f = F[i];
        int x = lower_bound(X.begin(), X.end(), d) - X.begin();
        int yl = lower_bound(Y.begin(), Y.end(), e) - Y.begin();
        int yr = lower_bound(Y.begin(), Y.end(), f) - Y.begin();
        for (int y = yl+1; y <= yr; y++) {
            V[encode(x, y)].emplace(encode(x+1, y));
        }
    }

    UnionFind uf((Xs+2)*(Ys+2));

    for (int i = 0; i <= Xs; i++) {
        for (int j = 0; j <= Ys; j++) {
            int cur = encode(i, j);
            int s = encode(i+1, j);
            int t = encode(i, j+1);
            if (!V[cur].count(s)) uf.unite(cur, s);
            if (!V[cur].count(t)) uf.unite(cur, t);
        }
    }

    int xz = lower_bound(X.begin(), X.end(), 0LL) - X.begin();
    int yz = lower_bound(Y.begin(), Y.end(), 0LL) - Y.begin();
    int Z = encode(xz, yz);

    long long ans = 0;
    for (int i = 0; i <= Xs; i++) {
        for (int j = 0; j <= Ys; j++) {
            int cur = encode(i, j);
            if (!uf.same(cur, Z)) continue;
            if (i == 0 || j == 0 || i == Xs || j == Ys) {
                cout << "INF\n";
                return 0;
            }
            ans += (X[i] - X[i-1]) * (Y[j] - Y[j-1]);
        }
    }

    cout << ans << "\n";

    return 0;
}

Measured memory_bytes: 629840