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

#define rep(i, n) for(int (i) = 0; (i) < (n); (i)++)
#define repp(i, n, m) for(int (i) = (n); (i) < (m); (i)++)
#define repn(i, n) for(int (i) = 1; (i) <= (n); (i)++)
#define repr(i, n) for(int (i) = (n-1); (i) >= 0; (i)--)
#define all(x) (x).begin(), (x).end()
#define lint long long
#define ulint unsigned long long
#define ldou long double
#define fi first
#define se second
#define setpre(x) std::cout << fixed << setprecision(x)
#define ii(x) int x; cin >> (x)
#define ii2(x, y) int x, y; cin >> (x) >> (y)
#define ii3(x, y, z) int x, y, z; cin >> (x) >> (y) >> (z)
#define out(x) cout << (x) << endl
#define outs(x) cout << (x) << " "
#define yn(x) cout << ((x)?("Yes"):("No")) << endl
#define YN(x) cout << ((x)?("YES"):("NO")) << endl
#define bit_c(x) __builtin_popcountll(x)

inline void logger(){ std::cout << " [LOGGER] " << endl; }
template<typename A, typename... B>
void logger(const A& a, const B&... b){
    cout << a << " , "; logger(b...);
}

typedef pair<lint, lint> P;
const lint MOD = 1000000007;
const lint MOD9 = 998244353;
const lint INF = MOD * MOD;
const int MAX = 4005*4005;

/* ...o(^-^)o... */

template<class T>
struct coordinate_compression{
    int sz;
    vector<T> arr;
    map<T, int> zip;
    vector<T> unzip;
    coordinate_compression(vector<T> arr){
        init(arr);
    }
    void init(vector<T> arr){
        sort(all(arr));
        arr.erase(unique(all(arr)), arr.end());
        rep(i, arr.size()){
            zip[arr[i]] = i;
            unzip.push_back(arr[i]);
        }
        sz = arr.size();
    }
    int get(T x){
        return zip[x];
    }
    const T &operator[](int k) const{
        return unzip[k];
    }
};

typedef tuple<lint, lint, lint> info;
lint area[MAX], seen[MAX];
int X, Y, id[4005][4005];
bool obs[MAX][4];


int get_id(int i, int j){
    if(i<0 || i>=X-1 || j<0 || j>=Y-1) return -1;
    return id[i][j];
}

int main(){
    int n, m; cin >> n >> m;
    vector<lint> x = {0}, y = {0};
    vector<info> ver, hor;

    rep(i, n){
        lint a,b,c; cin>>a>>b>>c;
        x.push_back(a); x.push_back(b); y.push_back(c);
        ver.push_back(info(a,b,c));
    }
    rep(i, m){
        lint a,b,c; cin>>a>>b>>c;
        x.push_back(a); y.push_back(b); y.push_back(c);
        hor.push_back(info(a,b,c));
    }

    coordinate_compression<lint> cx(x), cy(y);
    X = cx.sz, Y = cy.sz;
    int b = 0;
    rep(i, X-1) rep(j, Y-1){ id[i][j] = b; b++; }
    rep(i, X-1) rep(j, Y-1) area[id[i][j]] = (cx[i+1]-cx[i])*(cy[j+1]-cy[j]);
    
    rep(i, n){
        int a = cx.get(get<0>(ver[i])),
            b = cx.get(get<1>(ver[i])),
            c = cy.get(get<2>(ver[i]));
        repp(j, a, b){
            int u=id[j][c-1], v=id[j][c];
            obs[u][2] = true;
            obs[v][3] = true;
        }
    }
    rep(i, m){
        int d = cx.get(get<0>(hor[i])),
            e = cy.get(get<1>(hor[i])),
            f = cy.get(get<2>(hor[i]));
        repp(j, e, f){
            int u=id[d-1][j], v=id[d][j];
            obs[u][0] = true;
            obs[v][1] = true;
        }
    }

    int z = id[cx.get(0)][cy.get(0)];
    seen[z] = true;
    lint ans = 0;
    bool isinf = false;
    vector<P> d = {P(1,0),P(-1,0),P(0,1),P(0,-1)};
    queue<int> q; q.push(z);

    while(!q.empty()){
        int s = q.front(); q.pop();
        ans += area[s];
        rep(k, 4){
            if(obs[s][k]) continue;
            int t = get_id(s/(Y-1)+d[k].fi, s%(Y-1)+d[k].se);
            if(t<0){ isinf = true; break; }
            if(seen[t]) continue;
            seen[t] = true;
            q.push(t);
        }
        if(isinf) break;
    }
    if(isinf) out("INF"); else out(ans);
}

Measured memory_bytes: 224304