#include <functional>
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ull, ll> P;

struct line{
    ll left, right, hight;

    bool operator<(const line &b) const{
        if(hight != b.hight) return hight < b.hight;
        if(left != b.left) return left < b.left;
        return right < b.right;
    }
};

template <typename S>   //semi group
struct UnionFind
{
    using F = function<S(S, S)>;
    
    const F f;
    
    vector<int> par, rank;
    vector<S> dat;
    
    UnionFind(int n, const F f = [](S a, S b){return a + b;}) : f(f){
        par.resize(n);
        rank.resize(n);
        dat.resize(n);
        for(int i = 0; i < n; i++){
            par[i] = i;
            rank[i] = 0;
        }
    }
    
    int find(int i){
        if(i == par[i]) return i;
        return par[i] = find(par[i]);
    }
    
    bool same(int i, int j){
        return find(i) == find(j);
    }
    
    void unite(int i, int j){
        if(same(i, j)) return;
        i = find(i), j = find(j);
        if(rank[i] < rank[j]){
            par[i] = j;
            dat[j] = f(dat[i], dat[j]);
        }
        else{
            par[j] = i;
            dat[i] = f(dat[i], dat[j]);
            if(rank[i] == rank[j]) rank[i]++;
        }
    }
    
    S query(int i){
        return dat[find(i)];
    }
};

int main()
{
    int n, m;
    cin >> n >> m;
    line t[1002], y[1002];
    for(int i = 0; i < n; i++){
        ll a, b, c;
        cin >> a >> b >> c;
        t[i] = (line){min(a, b), max(a, b), c};
    }
    for(int i = 0; i < m; i++){
        ll d, e, f;
        cin >> d >> e >> f;
        y[i] = (line){min(e, f), max(e, f), d};
    }
    sort(t, t + n);
    for(int i = 1; i < n; i++){
        if(t[i].hight == t[i - 1].hight && t[i].left <= t[i - 1].right){
            t[i].left = min(t[i].left, t[i - 1].left);
            t[i].right = max(t[i].right, t[i - 1].right);
            t[i - 1].left = 0;
            t[i - 1].right = 0;
        }
    }
    sort(y, y + m);
    for(int i = 1; i < m; i++){
        if(y[i].hight == y[i - 1].hight && y[i].left <= y[i - 1].right){
            y[i].left = min(y[i].left, y[i - 1].left);
            y[i].right = max(y[i].right, y[i - 1].right);
            y[i - 1].left = 0;
            y[i - 1].right = 0;
        }
    }
    UnionFind<P> uf((n + 1) * (m + 1), [](P a, P b){return P(a.first + b.first, (a.second | b.second));});
    int ai, aj;
    for(int i = 0; i <= n; i++){
        for(int j = 0; j <= m; j++){
            if(i == 0 || i == n || j == 0 || j == m){
                uf.dat[i * m + j] = P(0, 1);
            }
            else{
                uf.dat[i * m + j] = P((ull)(t[i].hight - t[i - 1].hight) * (ull)(y[j].hight - y[j - 1].hight), 0);
                if(t[i].hight >= 0 && t[i - 1].hight <= 0 && y[j].hight >= 0 && y[j - 1].hight <= 0){
                    ai = i;
                    aj = j;
                }
            }
        }
    }
    for(int i = 1; i < n; i++){
        for(int j = 0; j < m; j++){
            if(y[j].left > t[i - 1].hight || y[j].right < t[i].hight) uf.unite(i * m + j, i * m + j + 1);
        }
    }
    for(int j = 1; j < m; j++){
        for(int i = 0; i < n; i++){
            if(t[i].left > y[j - 1].hight || t[i].right < y[j].hight) uf.unite(i * m + j, (i + 1) * m + j);
        }
    }
    P ans = uf.query(ai * m + aj);
    if(ans.second == 1) cout << "INF" << endl;
    else cout << ans.first << endl;
}


Measured memory_bytes: 26760