#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T, class U> using Pa = pair<T, U>;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;

template<class T>
class Compress {
    int N;
    map<T,int> idx;
    map<int,T> value;
    vec<T> v;
    vec<T> cmp;
public:
    Compress(){}
    void add(T x){v.push_back(x);}
    void build(){
        for(auto &x:v) cmp.push_back(x);
        sort(cmp.begin(),cmp.end());
        cmp.erase(unique(cmp.begin(),cmp.end()),cmp.end());
        N = cmp.size();
        for (int i=0;i<N;i++) idx[cmp[i]] = i;
    }
    int id(T val) {return idx[val];}
    T val(int id) {return cmp[id];}
    int size(){return N;}
};


class UnionFind{
private:
    vec<int> p,s;
    vec<ll> val;
    int cnt;
public:
    UnionFind(){}
    UnionFind(int N,vec<ll> v):cnt(N),s(N,1),p(N){
        iota(p.begin(),p.end(),0);
        val = v;
    }
    int find(int x){
        if(p[x]==x) return x;
        else return p[x] = find(p[x]);
    }
    void unite(int x,int y){
        x = find(x); y = find(y);
        if(x==y) return;
        if(s[x]>s[y]) swap(x,y);
        p[x] = y;
        s[y] += s[x];
        val[y] += val[x];
        cnt--;
    }
    bool is_same_set(int x,int y) {return find(x)==find(y);}
    int size(int x) {return s[find(x)];}
    int compnents_number(){return cnt;}
    ll getval(int x){return val[find(x)];}
};

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N,M;
    cin >> N >> M;
    Compress<int> cx,cy;
    vec<int> A(N),B(N),C(N),D(M),E(M),F(M);
    for(int i=0;i<N;i++){
        cin >> A[i] >> B[i] >> C[i];
        cy.add(C[i]);
        cx.add(A[i]),cx.add(B[i]);
    }
    for(int i=0;i<M;i++){
        cin >> D[i] >> E[i] >> F[i];
        cx.add(D[i]);
        cy.add(E[i]),cy.add(F[i]);
    }
    int inf = 1e9+1;
    cx.add(-inf),cx.add(inf);
    cy.add(-inf),cy.add(inf);
    cx.add(0),cy.add(0);
    cx.build(),cy.build();
    int H = cx.size(),W = cy.size();
//    cerr << "H : " << H << " W : " << W << "\n";
    int sx = 0,sy = 0;
    for(int i=0;i+1<H;i++) if(cx.val(i+1)<=0) sx = i;
    for(int j=0;j+1<W;j++) if(cy.val(j+1)<=0) sy = j;
//    cerr << sx << " " << sy << "\n";
    vec<set<int>> noX(H),noY(W);
    for(int i=0;i<N;i++){
        int y = cy.id(C[i]),l = cx.id(A[i]),r = cx.id(B[i]);
//        cerr << "i : " << i << " y : " << y << " l : " << l << " r : " << r << "\n";
        for(int j=l;j<r;j++) noY[y-1].insert(j);
    }
    for(int i=0;i<M;i++){
        int x = cx.id(D[i]),l = cy.id(E[i]),r = cy.id(F[i]);
        for(int j=l;j<r;j++) noX[x-1].insert(j);
    }
    vec<ll> v;
    for(int i=0;i<H;i++) for(int j=0;j<W;j++){
        if(i+1<H && j+1<W){
            ll h = cx.val(i+1)-cx.val(i),w = cy.val(j+1)-cy.val(j);
            v.push_back(h*w);
        }else{
            v.push_back(0);
        }
    }
    UnionFind uf(H*W,v);
    
    auto id = [&](int i,int j){
        return i*W+j;
    };
    
    for(int i=0;i<H;i++) for(int j=0;j<W;j++){
        if(i+1<H && !noX[i].count(j)) uf.unite(id(i,j),id(i+1,j));
        if(j+1<W && !noY[j].count(i)) uf.unite(id(i,j),id(i,j+1));
    }
    for(auto x:{0,H-1}) for(auto y:{0,W-1}){
        if(uf.is_same_set(id(sx,sy),id(x,y))){
            cout << "INF\n";
            return 0;
        }
    }
//    cerr << uf.size(id(sx,sy)) << "\n";
    cout << uf.getval(id(sx,sy)) << "\n";
}

Measured memory_bytes: 450652