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

using namespace std;

using ll =  long long;
using Pii = pair<int, int>;

constexpr int INF = 1 << 30;
constexpr int dyx[4][2] = {
    { 0, 1}, {-1, 0}, {0,-1}, {1, 0}
};

struct Segment {
    ll x1, x2, y1, y2;
    Segment(ll a,  ll b, ll c, bool is_vertical) {
        if(is_vertical) {
            x1 = a;
            x2 = b;
            y1 = y2 = c;
        } else {
            x1 = x2 = a;
            y1 = b;
            y2 = c;
        }
    }
};

int main() {
    int n, m; ll a, b, c;
    cin >> n >> m;

    vector<Segment> segs;
    set<ll> xs, ys;
    xs.insert(0);
    ys.insert(0);
    for(int i=0;i<n+m;++i) {
        cin >> a >> b >> c;
        segs.push_back(Segment(a, b, c, i < n));
        xs.insert(segs.back().x1);
        xs.insert(segs.back().x2);
        ys.insert(segs.back().y1);
        ys.insert(segs.back().y2);
    }

    int nx = xs.size()*2+1, ny = ys.size()*2+1;

    map<ll, ll> mpx, mpy;   // 圧縮後の座標への変換
    vector<ll> widthx(nx, 0), widthy(ny, 0);  // 変換後のフィールドでの各マスの幅
    {
        int i = 0;
        ll prev = -INF;
        for(ll x: xs) {
            mpx[x] = i*2+1;
            widthx[i*2] = (prev == -INF) ? INF : (x - prev);
            prev = x;
            i++;
        }
        widthx[i*2] = INF;
        i = 0;
        prev = -INF;
        for(ll y: ys) {
            mpy[y] = i*2+1;
            widthy[i*2] = (prev == -INF) ? INF : (y - prev);
            prev = y;
            i++;
        }
        widthy[i*2] = INF;
    }

    vector<vector<bool>> matrix(nx, vector<bool>(ny, true)); // 変換後の草原
    vector<vector<bool>> used(nx, vector<bool>(ny, false));
    for(int i=0;i<n+m;++i) {
        // x と y のいずれかは単一の値しか取らないはず
        for(ll x=mpx[segs[i].x1];x<=mpx[segs[i].x2];++x) {
            for(ll y=mpy[segs[i].y1] ;y<=mpy[segs[i].y2] ;++y) {
                matrix[x][y] = false;
            }
        }
    }

    // 変換後の草原の上で BFS
    ll ans = 0LL;
    queue<Pii> que;
    que.emplace(mpx[0], mpy[0]);
    used[mpx[0]][mpy[0]] = true;
    {
        ll x, y;
        while(!que.empty()) {
            tie(x, y) = que.front(); que.pop();
            if(widthx[x] == INF || widthy[y] == INF) {
                ans = -1;
                break;
            }
            ans += widthx[x] * widthy[y];
            for(int k=0;k<4;++k) {
                ll xx = x + dyx[k][0], yy = y + dyx[k][1];
                if(0 <= xx && xx < nx && 0 <= yy && yy < ny && !used[xx][yy] && matrix[xx][yy]) {
                    que.emplace(xx, yy);
                    used[xx][yy] = true;
                }
            }
        }
    }

    if(ans == -1) {
        cout << "INF" << endl;
        return 0;
    }
    cout << ans << endl;
}
