#include <iostream>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <queue>
#include <set>
#include <map>

using namespace std;
typedef long long ll;
typedef pair<int, int> P;

const ll INF = 1000000001;
set<ll> sth, stw;

int N, M;
int A[1000], B[1000], C[1000];
int D[1000], E[1000], F[1000];

map<ll, int> mph, mpw;
bool l[4000][4000], r[4000][4000], u[4000][4000], d[4000][4000];
bool used[4000][4000];

int w_max, h_max;
bool is_inf;
void dfs(int i, int j){
    used[i][j] = true;
    queue<P> que;
    if(i >= h_max-1 || j >= w_max-1 || i <= 0 || j <= 0) {
        is_inf = true;
        return;
    }
    if(r[i][j] && !used[i][j+1]) {
        que.push(P(i, j+1));
        used[i][j+1] = true;
    }
    if(l[i][j] && !used[i][j-1]) {
        que.push(P(i, j-1));
        used[i][j-1] = true;
    }
    if(d[i][j] && !used[i+1][j]) {
        que.push(P(i+1, j));
        used[i+1][j] = true;
    }
    if(u[i][j] && !used[i-1][j]) {
        que.push(P(i-1, j));
        used[i-1][j] = true;
    }
    while(!que.empty()){
        P p = que.front();
        que.pop();
        int i = p.first;
        int j = p.second;
        used[i][j] = true;
        if(i >= h_max-1 || j >= w_max-1 || i <= 0 || j <= 0) {
            is_inf = true;
            continue;
        }
        if(r[i][j] && !used[i][j+1]) {
            que.push(P(i, j+1));
            used[i][j+1] = true;
        }
        if(l[i][j] && !used[i][j-1]) {
            que.push(P(i, j-1));
            used[i][j-1] = true;
        }
        if(d[i][j] && !used[i+1][j]) {
            que.push(P(i+1, j));
            used[i+1][j] = true;
        }
        if(u[i][j] && !used[i-1][j]) {
            que.push(P(i-1, j));
            used[i-1][j] = true;
        }
    }
}

vector<int> val_h, val_w;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout << setprecision(10) << fixed;
    cin >> N >> M;
    sth.insert(-INF); sth.insert(INF);
    stw.insert(-INF); stw.insert(INF);
    for(int i = 0; i < N; i++){
        cin >> A[i] >> B[i] >> C[i];
        sth.insert(A[i]); sth.insert(B[i]); stw.insert(C[i]);
    }
    for(int i = 0; i < M; i++){
        cin >> D[i] >> E[i] >> F[i];
        stw.insert(E[i]); stw.insert(F[i]); sth.insert(D[i]);
    }
    int cur = 0;
    h_max = sth.size()-1;
    w_max = stw.size()-1;
    for(auto h : sth){
        mph[h] = cur;
        cur++;
        val_h.push_back(h);
    }
    cur = 0;
    for(auto w : stw){
        mpw[w] = cur;
        cur++;
        val_w.push_back(w);
    }
    for(int i = 0; i < 4000; i++){
        for(int j = 0; j < 4000; j++){
            l[i][j] = true;
            r[i][j] = true;
            u[i][j] = true;
            d[i][j] = true;
        }
    }

    // 縦線
    for(int i = 0; i < N; i++){
        int u_ = mph[A[i]];
        int d_ = mph[B[i]];
        int w = mpw[C[i]];
        for(int h = u_; h < d_; h++){
            r[h][w-1] = false;
            l[h][w] = false;
        }
    }

    // 横線
    for(int i = 0; i < M; i++){
        int l_ = mpw[E[i]];
        int r_ = mpw[F[i]];
        int h = mph[D[i]];
        for(int w = l_; w < r_; w++){
            d[h-1][w] = false;
            u[h][w] = false;
        }
    }
    int start_h;
    for(auto i : mph){
        int h = i.first;
        int idx = i.second;
        if(h > 0) break;
        start_h = idx;
    }
    int start_w;
    for(auto i : mpw){
        int w = i.first;
        int idx = i.second;
        if(w > 0) break;
        start_w = idx;
    }
    if(h_max >= 3200 || w_max >= 3200) return 0;
    dfs(start_h, start_w);
    if(is_inf){
        cout << "INF" << endl;
        return 0;
    }
    ll ans = 0;
    for(int i = 0; i < h_max-1; i++){
        for(int j = 0; j < w_max-1; j++){
            if(!used[i][j]) continue;
            ll h = val_h[i+1]-val_h[i];
            ll w = val_w[j+1]-val_w[j];
            ans += h*w;
        }
    }
    cout << ans << endl;
}

Measured memory_bytes: 78596