#include <bits/stdc++.h>

#define fst(t) std::get<0>(t)
#define snd(t) std::get<1>(t)
#define thd(t) std::get<2>(t)
#define unless(p) if(!(p))
#define until(p) while(!(p))

using ll = std::int64_t;
using P = std::tuple<int,int>;

constexpr int INF = 1000000000;
int N, M;
int A[1100], B[1100], C[1100];
int D[1100], E[1100], F[1100];
std::vector<int> xs, ys;
bool filled[7100][7100], visited[7100][7100];
std::stack<P> st;
int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};

ll area(){
    ll res = 0;

    for(int i=0;i+1<xs.size();++i){
        for(int j=0;j+1<ys.size();++j){
            unless(visited[i*2+1][j*2+1]){continue;}

            if(i == 0 || i + 1 == xs.size() - 1 ||
               j == 0 || j + 1 == ys.size() - 1){
                return -1;
            }

            int x1 = xs[i], x2 = xs[i+1], y1 = ys[j], y2 = ys[j+1];
            res += 1ll * (x2 - x1) * (y2 - y1);
        }
    }

    return res;
}

int main(){
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);

    xs.emplace_back(0);

    xs.emplace_back(-INF-1);
    xs.emplace_back(-INF);
    xs.emplace_back(INF);
    xs.emplace_back(INF+1);

    ys.emplace_back(0);

    ys.emplace_back(-INF-1);
    ys.emplace_back(-INF);
    ys.emplace_back(INF);
    ys.emplace_back(INF+1);

    std::cin >> N >> M;

    for(int i=0;i<N;++i){
        std::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){
        std::cin >> D[i] >> E[i] >> F[i];
      
        xs.emplace_back(D[i]);
        ys.emplace_back(E[i]);
        ys.emplace_back(F[i]);
    }

    std::sort(xs.begin(), xs.end());
    xs.erase(std::unique(xs.begin(), xs.end()), xs.end());
    std::sort(ys.begin(), ys.end());
    ys.erase(std::unique(ys.begin(), ys.end()), ys.end());

    for(int i=0;i<N;++i){
        A[i] = std::lower_bound(xs.begin(), xs.end(), A[i]) - xs.begin();
        B[i] = std::lower_bound(xs.begin(), xs.end(), B[i]) - xs.begin();
        C[i] = std::lower_bound(ys.begin(), ys.end(), C[i]) - ys.begin();

        for(int j=A[i]*2;j<=B[i]*2;++j){
            filled[j][C[i]*2] = true;
        }
    }

    for(int i=0;i<M;++i){
        D[i] = std::lower_bound(xs.begin(), xs.end(), D[i]) - xs.begin();
        E[i] = std::lower_bound(ys.begin(), ys.end(), E[i]) - ys.begin();
        F[i] = std::lower_bound(ys.begin(), ys.end(), F[i]) - ys.begin();

        for(int j=E[i]*2;j<=F[i]*2;++j){
            filled[D[i]*2][j] = true;
        }
    }

    int sx = (std::lower_bound(xs.begin(), xs.end(), 0) - xs.begin()) * 2,
        sy = (std::lower_bound(ys.begin(), ys.end(), 0) - ys.begin()) * 2;
    visited[sx][sy] = true;
    st.emplace(sx, sy);
    
    int mx_x = xs.size() * 2, mx_y = ys.size() * 2;

    // for(int j=0;j<mx_y;++j){
    //     for(int i=0;i<mx_x;++i){
    //         std::cout << filled[i][j];
    //     }
    //     std::cout << std::endl;
    // }
    // std::cout << "----------" << std::endl;

    until(st.empty()){
        int x, y;
        std::tie(x, y) = st.top();
        st.pop();

        for(int i=0;i<4;++i){
            int nx = x + dx[i], ny = y + dy[i];

            if(nx < 0 || nx >= mx_x || ny < 0 || ny >= mx_y){
                continue;
            }

            if(filled[nx][ny] || visited[nx][ny]){
                continue;
            }

            visited[nx][ny] = true;
            st.emplace(nx, ny);
        }
    }

    // for(int j=0;j<mx_y;++j){
    //     for(int i=0;i<mx_x;++i){
    //         std::cout << visited[i][j];
    //     }
    //     std::cout << std::endl;
    // }
    // std::cout << "----------" << std::endl;

    ll res = area();

    if(res >= 0){
        std::cout << res << std::endl;
    }else{
        std::cout << "INF" << std::endl;
    }
}


Measured memory_bytes: 164944