#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
#define REP(i,n) for (ll i = 0; i < (n); ++i)
#define RREP(i, n) for (ll i = (n) - 1; i >= 0; --i)
#define ALL(v) (v).begin(), (v).end()

const ll INF = numeric_limits<ll>::max();
const ll NINF = numeric_limits<ll>::min();

int main(){
    ll n, m;
    cin >> n >> m;
    vector<array<ll, 3>> vline, hline;

    vector<ll> xs = {NINF, 0, INF};
    vector<ll> ys = {NINF, 0, INF};

    REP(i, n){
        ll ai, bi, ci;
        cin >> ai >> bi >> ci;
        vline.push_back({ai, bi, ci});
        xs.push_back(ai); xs.push_back(bi);
        ys.push_back(ci);
    }
    REP(j, m){
        ll di, ei, fi;
        cin >> di >> ei >> fi;
        hline.push_back({di, ei, fi});
        xs.push_back(di);
        ys.push_back(ei); ys.push_back(fi);
    }

    sort(ALL(xs));
    xs.erase(unique(ALL(xs)), xs.end());
    sort(ALL(ys));
    ys.erase(unique(ALL(ys)), ys.end());

    const ll nx = xs.size(), ny = ys.size();

    unordered_map<ll, ll> x2i, y2i;
    REP(i, xs.size()){ x2i[xs.at(i)] = x2i.size(); }
    REP(i, ys.size()){ y2i[ys.at(i)] = y2i.size(); }

    REP(i, n){
        vline.at(i).at(0) = x2i.at(vline.at(i).at(0));
        vline.at(i).at(1) = x2i.at(vline.at(i).at(1));
        vline.at(i).at(2) = y2i.at(vline.at(i).at(2));
    }

    REP(i, m){
        hline.at(i).at(0) = x2i.at(hline.at(i).at(0));
        hline.at(i).at(1) = y2i.at(hline.at(i).at(1));
        hline.at(i).at(2) = y2i.at(hline.at(i).at(2));
    }

    vector<vector<array<bool, 2>>> has_wall(
        nx, vector<array<bool, 2>>(ny, {false, false}));
    REP(i, n){
        const ll yi = vline.at(i).at(2);
        for(ll xi = vline.at(i).at(0); xi < vline.at(i).at(1); ++xi){
            has_wall.at(xi).at(yi).at(0) = true;
        }
    }
    REP(i, m){
        const ll xi = hline.at(i).at(0);
        for(ll yi = hline.at(i).at(1); yi < hline.at(i).at(2); ++yi){
            has_wall.at(xi).at(yi).at(1) = true;
        }
    }

    vector<vector<bool>> visited(nx, vector<bool>(ny, false));
    visited.at(x2i.at(0)).at(y2i.at(0)) = true;
    queue<pair<ll, ll>> que;
    que.emplace(x2i.at(0), y2i.at(0));

    ll ans = 0;
    while(!que.empty()){
        const auto p = que.front(); que.pop();
        ll xi = p.first, yi = p.second;

        if(xi == 0 || yi == 0 || xi + 2 >= nx || yi + 2 >= ny){
            cout << "INF" << endl;
            return 0;
        }

        const ll x1 = xs.at(xi);
        const ll y1 = ys.at(yi);
        const ll x2 = xs.at(xi + 1);
        const ll y2 = ys.at(yi + 1);
        // cerr << x1 << ", " << y1 << " - " << x2 << ", " << y2 << endl;
        ans += (x2 - x1) * (y2 - y1);

        // up
        if(!has_wall.at(xi).at(yi).at(1) && xi > 0 && !visited.at(xi - 1).at(yi)){
            visited.at(xi - 1).at(yi) = true;
            que.emplace(xi - 1, yi);
        }

        // down
        if(!has_wall.at(xi + 1).at(yi).at(1) && !visited.at(xi + 1).at(yi)){
            visited.at(xi + 1).at(yi) = true;
            que.emplace(xi + 1, yi);
        }

        // left
        if(!has_wall.at(xi).at(yi).at(0) && yi > 0 && !visited.at(xi).at(yi - 1)){
            visited.at(xi).at(yi - 1) = true;
            que.emplace(xi, yi - 1);
        }

        // right
        if(!has_wall.at(xi).at(yi + 1).at(0) && !visited.at(xi).at(yi + 1)){
            visited.at(xi).at(yi + 1) = true;
            que.emplace(xi, yi + 1);
        }
    }
    cout << ans << endl;
    return 0;
}


Measured memory_bytes: 22924