#include <bits/stdc++.h>
#define err(args...) {}
#ifdef DEBUG
#include "_debug.cpp"
#endif
using namespace std;
using ll = long long;
using ld = long double;
template <typename T> using lim = numeric_limits<T>;
template <typename T> istream& operator>>(istream& is, vector<T>& a) { for(T& x : a) { is >> x; } return is; }
template <typename X, typename Y> istream& operator>>(istream& is, pair<X, Y>& p) { return is >> p.first >> p.second; }
const int N = 1000;
int blocked[2 * (3 * N + 2)][2 * (3 * N + 2)];
int vis[2 * (3 * N + 2)][2 * (3 * N + 2)];
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    vector<int> hori_x1(n), hori_x2(n), hori_y(n);
    vector<int> vert_y1(m), vert_y2(m), vert_x(m);
    for(int i = 0; i < n; i++) {
        cin >> hori_x1[i] >> hori_x2[i] >> hori_y[i];
    }
    for(int i = 0; i < m; i++) {
        cin >> vert_x[i] >> vert_y1[i] >> vert_y2[i];
    }
    int INF = 1'000'000'000 + 1;
    vector<int> xs = {0, INF}, ys = {0, INF};
    for(auto& v : {hori_x1, hori_x2, vert_x}) {
        for(int x : v) {
            xs.push_back(x);
        }
    }
    for(auto& v : {vert_y1, vert_y2, hori_y}) {
        for(int y : v) {
            ys.push_back(y);
        }
    }
    sort(xs.begin(), xs.end());
    xs.erase(unique(xs.begin(), xs.end()), xs.end());
    sort(ys.begin(), ys.end());
    ys.erase(unique(ys.begin(), ys.end()), ys.end());
    auto comp = [](int coord, const vector<int>& s) { return lower_bound(s.begin(), s.end(), coord) - s.begin(); };
    for(int i = 0; i < n; i++) {
        int x1 = comp(hori_x1[i], xs), x2 = comp(hori_x2[i], xs), y = comp(hori_y[i], ys);
        for(int c = x1; c < x2; c++) {
            blocked[2 * c][2 * y] = 1;
            blocked[2 * c + 1][2 * y] = 1;
        }
        blocked[2 * x2][2 * y] = 1;
    }
    for(int i = 0; i < m; i++) {
        int y1 = comp(vert_y1[i], ys), y2 = comp(vert_y2[i], ys), x = comp(vert_x[i], xs);
        for(int c = y1; c < y2; c++) {
            blocked[2 * x][2 * c] = 1;
            blocked[2 * x][2 * c + 1] = 1;
        }
        blocked[2 * x][2 * y2] = 1;
    }
    queue<pair<int, int>> q;
    q.push({2 * comp(0, xs), 2 * comp(0, ys)});
    vis[q.front().first][q.front().second] = true;
    int di[] = {-1, 1, 0, 0};
    int dj[] = {0, 0, -1, 1};
    ll ans = 0;
    while(not q.empty()) {
        auto [i, j] = q.front(); q.pop();
        ans += ll(xs[(i + 1) / 2] - xs[i / 2]) * ll(ys[(j + 1) / 2] - ys[j / 2]);
        for(int d = 0; d < 4; d++) {
            int ni = i + di[d];
            int nj = j + dj[d];
            if(0 <= ni and ni < 2 * xs.size() and 0 <= nj and nj < 2 * ys.size() and not blocked[ni][nj] and not vis[ni][nj]) {
                q.push({ni, nj});
                vis[ni][nj] = true;
            }
        }
    }
    if(vis[2 * comp(INF, xs)][2 * comp(INF, ys)]) {
        cout << "INF" << endl;
    } else {
        cout << ans << endl;
    }
    return 0;
}