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

struct UnionFind{
    int num;
    vector<int> par,rank;
    UnionFind(int n):num(n),par(n),rank(n,1){
        iota(par.begin(),par.end(),0);
    }
    int root(int x){
        if (par[x]==x) return x;
        return par[x]=root(par[x]);
    }
    bool merge(int x, int y){
        x=root(x),y=root(y);
        if (x==y) return false;
        if (rank[x]<rank[y]) swap(x,y);
        par[y]=x;
        rank[x]+=rank[y];
        --num;
        return true;
    }
    bool same(int x, int y){
        return root(x)==root(y);
    }
    int size(int x){
        return rank[root(x)];
    }
    int count(){
        return num;
    }
};

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N,M; cin >> N >> M;
    vector<ll> A(N),B(N),C(N),D(M),E(M),F(M),xs,ys;
    for (int i=0;i<N;++i){
        cin >> A[i] >> B[i] >> C[i];
        xs.emplace_back(A[i]);
        xs.emplace_back(B[i]);
        ys.emplace_back(C[i]);
    }
    for (int i=0;i<M;++i){
        cin >> D[i] >> E[i] >> F[i];
        xs.emplace_back(D[i]);
        ys.emplace_back(E[i]);
        ys.emplace_back(F[i]);
    }
    sort(xs.begin(),xs.end());
    sort(ys.begin(),ys.end());
    xs.erase(unique(xs.begin(),xs.end()),xs.end());
    ys.erase(unique(ys.begin(),ys.end()),ys.end());
    for (int i=0;i<N;++i){
        A[i]=lower_bound(xs.begin(),xs.end(),A[i])-xs.begin();
        B[i]=lower_bound(xs.begin(),xs.end(),B[i])-xs.begin();
        C[i]=lower_bound(ys.begin(),ys.end(),C[i])-ys.begin();
    }
    for (int i=0;i<M;++i){
        D[i]=lower_bound(xs.begin(),xs.end(),D[i])-xs.begin();
        E[i]=lower_bound(ys.begin(),ys.end(),E[i])-ys.begin();
        F[i]=lower_bound(ys.begin(),ys.end(),F[i])-ys.begin();
    }
    int X=xs.size()-1,Y=ys.size()-1;
    int sx=lower_bound(xs.begin(),xs.end(),0)-xs.begin()-1;
    int sy=lower_bound(ys.begin(),ys.end(),0)-ys.begin()-1;
    if (sx<0||sy<0){cout << "INF" << '\n'; return 0;}
    int s=sx*Y+sy;
    vector<vector<bool>> wy(Y+1,vector<bool>(X)),wx(X+1,vector<bool>(Y));
    for (int i=0;i<N;++i){
        for (int j=A[i];j<B[i];++j){
            wy[C[i]][j]=true;
        }
    }
    for (int i=0;i<M;++i){
        for (int j=E[i];j<F[i];++j){
            wx[D[i]][j]=true;
        }
    }
    UnionFind uf(X*Y+1);
    for (int i=0;i<=Y;++i){
        for (int j=0;j<X;++j){
            if (!wy[i][j]){
                if (i==0) uf.merge(j*Y+i,X*Y);
                else if (i==Y) uf.merge(j*Y+i-1,X*Y);
                else uf.merge(j*Y+i-1,j*Y+i);
            }
        }
    }
    for (int i=0;i<=X;++i){
        for (int j=0;j<Y;++j){
            if (!wx[i][j]){
                if (i==0) uf.merge(i*Y+j,X*Y);
                else if (i==X) uf.merge((i-1)*Y+j,X*Y);
                else uf.merge((i-1)*Y+j,i*Y+j);
            }
        }
    }
    if (uf.same(s,X*Y)){cout << "INF" << '\n'; return 0;}
    ll ans=0;
    for (int i=0;i<X*Y;++i) if (uf.same(s,i)){
        ans+=(xs[i/Y+1]-xs[i/Y])*(ys[i%Y+1]-ys[i%Y]);
    }
    cout << ans << '\n';
}