#include <iostream>
#include <cstring>
#include <map>
#include <unordered_map>
#include <queue>
#include <set>
#include <vector>
using namespace std;
int main() {
    int n, m; cin >> n >> m;
    int A[n], B[n], C[n], D[m], E[m], F[m];
    set<int> xs, ys;
    for (int i = 0; i < n; i++) {
        cin >> A[i] >> B[i] >> C[i];
        xs.insert(A[i]);
        xs.insert(B[i]);
        ys.insert(C[i]);
    }
    for (int i = 0; i < m; i++) {
        cin >> D[i] >> E[i] >> F[i];
        xs.insert(D[i]);
        ys.insert(E[i]);
        ys.insert(F[i]);
    }
    unordered_map<int, int> xi, yi;
    const int N = xs.size(), M = ys.size();
    vector<int> ix(N), iy(M);
    {
        int i = 0;
        for (int x : xs) { ix[i] = x; xi[x] = i++; }
        i = 0;
        for (int y : ys) { iy[i] = y; yi[y] = i++; }
    }
    queue<pair<int, int> > q;
    long long ans = 0;
    const int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
    bool dir[N+1][M+1][4];
    for (int i = 0; i <= N; i++)
        for (int j = 0; j <= M; j++)
            for (int k = 0; k < 4; k++)
                dir[i][j][k] = true;
    for (int i = 0; i < n; i++) {
        // A[i], C[i] --- B[i], C[i];
        const int i1 = xi[A[i]], i2 = xi[B[i]], j = yi[C[i]];
        for (int ii = i1+1; ii <= i2; ii++) {
            dir[ii][j][1] = false;
            dir[ii][j+1][3] = false;
        }
    }
    for (int i = 0; i < m; i++) {
        const int i1 = xi[D[i]], j1 = yi[E[i]], j2 = yi[F[i]];
        for (int jj = j1+1; jj <= j2; jj++) {
            dir[i1][jj][0] = false;
            dir[i1+1][jj][2] = false;
        }
    }

    if (0 <= *xs.begin() || *xs.rbegin() <= 0 || 0 <= *ys.begin() || *ys.rbegin() <= 0) {
        cout << "INF\n";
        return 0;
    }
    
    bool used[N+1][M+1];
    memset(used, 0, sizeof used);
    for (int i = 1; i < N; i++) {
        if (ix[i-1] <= 0 && 0 <= ix[i]) {
            for (int j = 1; j < M; j++) {
                if (iy[j-1] <= 0 && 0 <= iy[j]) {
                    ans += (long long)(ix[i] - ix[i-1]) * (iy[j] - iy[j-1]);
                    q.push({i, j});
                    used[i][j] = true;
                }
            }
        }
    }
            
    while (!q.empty()) {
        int i = q.front().first, j = q.front().second;
        q.pop();
        // cerr << i << " " << j << " " << ix[i] << " " << iy[j] << endl;
        for (int k = 0; k < 4; k++) {
            if (dir[i][j][k]) {
                int i1 = i + dx[k], j1 = j + dy[k];
                if (0 <= i1 && i1 <= N && 0 <= j1 && j1 <= M && !used[i1][j1]) {
                    if (i1 == 0 || j1 == 0 || i1 == N || j1 == M) {
                        // cerr << i1 << ' ' << j1 << ' ' << ix[i1] << ' ' << iy[j1] << endl;
                        cout << "INF\n";
                        return 0;
                    }
                    ans += (long long)(ix[i1] - ix[i1-1]) * (iy[j1] - iy[j1-1]);
                    q.push({i1, j1});
                    used[i1][j1] = true;
                }
            }
        }
    }
    cout << ans << endl;
}
