// Generated by 1.1.7.1 https://github.com/kyuridenamida/atcoder-tools

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

const i64 MOD = 1e9 + 7;
const i64 INF = i64(1e18) + 7;


template <typename T>
bool chmin(T& x, T y){
    if(x > y){
        x = y;
        return true;
    }
    return false;
}

template <typename T>
bool chmax(T& x, T y){
    if(x < y){
        x = y;
        return true;
    }
    return false;
}

template<typename T>
struct Compression{
    vector<T> compvec;
    unordered_map<T, int> th;
    Compression(vector<T>& inp){//圧縮する
        compvec = inp;
        sort(compvec.begin(), compvec.end());
        compvec.erase(unique(compvec.begin(), compvec.end()), compvec.end());
    }
    int Index(T val){//圧縮を元に対応するインデックスを返す
        if(th.find(val) != th.end())
            return th[val];
        auto it = lower_bound(compvec.begin(), compvec.end(), val);
        return th[val] = distance(compvec.begin(), it);
    }
    vector<T>& operator*(){
        return compvec;
    }
};

struct UnionFind{
    vector<int> par;
    int count;
    UnionFind(int n) : par(n, -1), count(0){}
    int Find(int x){return par[x] < 0 ? x : Find(par[x]);}
    int Size(int x){return par[x] < 0 ? -par[x] : Size(par[x]);}
    bool Unite(int x, int y){
        x = Find(x);
        y = Find(y);
        if(x == y)
            return false;
        if(par[x] > par[y])
            swap(x, y);
        par[x] += par[y];
        par[y] = x;
        return ++count;
    }
};


void solve(long long n, long long m, std::vector<long long> a, std::vector<long long> b, std::vector<long long> c, std::vector<long long> d, std::vector<long long> e, std::vector<long long> f){
    vector<int> ccx{0, 1, -1, MOD, MOD + 1, -MOD, -MOD - 1};
    vector<int> ccy{0, 1, -1, MOD, MOD + 1, -MOD, -MOD - 1};
    for(int i = 0; i < n; ++i){
        ccx.emplace_back(a[i]);
        ccx.emplace_back(b[i]);
        ccy.emplace_back(c[i]);
    }
    for(int i = 0; i < m; ++i){
        ccy.emplace_back(e[i]);
        ccy.emplace_back(f[i]);
        ccx.emplace_back(d[i]);
    }
    Compression<int> cx(ccx);
    Compression<int> cy(ccy);

    UnionFind uf((*cx).size() * (*cy).size());

    auto idx = [&](int i, int j){
        return i * (*cy).size() + j;
    };

    set<pair<pair<int,int>, pair<int,int>>> ign;
    for(int i = 0; i < n; ++i){
        int sx = cx.Index(a[i]);
        int ex = cx.Index(b[i]);
        int y = cy.Index(c[i]);
        for(int x = sx; x < ex; ++x)
            ign.emplace(minmax(make_pair(x, y - 1), make_pair(x, y)));
    }
    for(int i = 0; i < m; ++i){
        int x = cx.Index(d[i]);
        int sy = cy.Index(e[i]);
        int ey = cy.Index(f[i]);
        for(int y = sy; y < ey; ++y)
            ign.emplace(minmax(make_pair(x - 1, y), make_pair(x, y)));
    }

    for(int i = 0; i < (*cx).size(); ++i){
        for(int j = 0; j < (*cy).size(); ++j){
            auto p = make_pair(i, j);
            auto p1 = make_pair(i + 1, j);
            auto p2 = make_pair(i, j + 1);
            if(i + 1 != (*cx).size() && ign.find(minmax(p, p1)) == ign.end())
                uf.Unite(idx(i, j), idx(i + 1, j));
            if(j + 1 != (*cy).size() && ign.find(minmax(p, p2)) == ign.end())
                uf.Unite(idx(i, j), idx(i, j + 1));
        }
    }

    int id = idx(cx.Index(0), cy.Index(0));
    int uid = uf.Find(id);
    if(uid == uf.Find(0)){
        cout << "INF" << endl;
        return;
    }
    i64 ans = 0;
    for(int i = 0; i < (*cx).size(); ++i){
        for(int j = 0; j < (*cy).size(); ++j){
            if(uf.Find(idx(i, j)) == uid){
                if(i + 1 == (*cx).size() || j + 1 == (*cy).size()){
                    cout << "INF" << endl;
                    return;
                }
                i64 xd = (*cx)[i + 1] - (*cx)[i];
                i64 yd = (*cy)[j + 1] - (*cy)[j];
                ans += xd * yd;
            }
        }
    }
    cout << ans << endl;
}


signed main(){
    long long N;
    scanf("%lld",&N);
    long long M;
    scanf("%lld",&M);
    std::vector<long long> A(N);
    std::vector<long long> B(N);
    std::vector<long long> C(N);
    for(int i = 0 ; i < N ; i++){
        scanf("%lld",&A[i]);
        scanf("%lld",&B[i]);
        scanf("%lld",&C[i]);
    }
    std::vector<long long> D(M);
    std::vector<long long> E(M);
    std::vector<long long> F(M);
    for(int i = 0 ; i < M ; i++){
        scanf("%lld",&D[i]);
        scanf("%lld",&E[i]);
        scanf("%lld",&F[i]);
    }
    solve(N, M, std::move(A), std::move(B), std::move(C), std::move(D), std::move(E), std::move(F));
    return 0;
}


Measured memory_bytes: 258596