#include <bits/stdc++.h>
#define _overload3(_1,_2,_3,name,...)name
#define _rep(i,n)repi(i,0,n)
#define repi(i,a,b)for(int i=int(a),i##_len=(b);i<i##_len;++i)
#define MSVC_UNKO(x)x
#define rep(...)MSVC_UNKO(_overload3(__VA_ARGS__,repi,_rep,_rep)(__VA_ARGS__))
#define all(c)c.begin(),c.end()
#define write(x)cout<<(x)<<'\n'
using namespace std; using ll = long long; template<class T>using vv = vector<vector<T>>;
template<class T>auto vvec(int n, int m, T v) { return vv<T>(n, vector<T>(m, v)); }
constexpr int INF = 1 << 29, MOD = int(1e9) + 7; constexpr ll LINF = 1LL << 60;
struct aaa { aaa() { cin.tie(0); ios::sync_with_stdio(0); cout << fixed << setprecision(10); }; }aaaa;

constexpr int dy[4] = { 0,1,0,-1 }, dx[4] = { 1,0,-1,0 };

int N, M;
vector<int> A, B, C, D, E, F;

int main() {
    cin >> N >> M;
    A.resize(N); B.resize(N); C.resize(N);
    D.resize(M); E.resize(M); F.resize(M);
    rep(i, N) cin >> A[i] >> B[i] >> C[i];
    rep(i, M) cin >> D[i] >> E[i] >> F[i];

    vector<int> xcmp, ycmp;
    rep(i, N) {
        xcmp.push_back(A[i]);
        xcmp.push_back(B[i]);
        ycmp.push_back(C[i]);
    }
    rep(i, M) {
        xcmp.push_back(D[i]);
        ycmp.push_back(E[i]);
        ycmp.push_back(F[i]);
    }
    sort(xcmp.begin(), xcmp.end());
    xcmp.erase(unique(xcmp.begin(), xcmp.end()), xcmp.end());
    sort(ycmp.begin(), ycmp.end());
    ycmp.erase(unique(ycmp.begin(), ycmp.end()), ycmp.end());

    int H = (int)xcmp.size() + 1, W = (int)ycmp.size() + 1;
    vv<int> cannotgo = vvec(H, W, 0);
    rep(i, H) {
        cannotgo[i][0] |= 1 << 3;
        cannotgo[i][W - 1] |= 1 << 1;
    }
    rep(j, W) {
        cannotgo[0][j] |= 1 << 2;
        cannotgo[H - 1][j] |= 1 << 0;
    }

    rep(i, N) {
        int y = lower_bound(all(ycmp), C[i]) - ycmp.begin();
        int xl = lower_bound(all(xcmp), A[i]) - xcmp.begin();
        int xh = lower_bound(all(xcmp), B[i]) - xcmp.begin();
        rep(x, xl + 1, xh + 1) {
            cannotgo[x][y] |= 1 << 1;
            cannotgo[x][y + 1] |= 1 << 3;
        }
    }
    rep(i, M) {
        int x = lower_bound(all(xcmp), D[i]) - xcmp.begin();
        int yl = lower_bound(all(ycmp), E[i]) - ycmp.begin();
        int yh = lower_bound(all(ycmp), F[i]) - ycmp.begin();
        rep(y, yl + 1, yh + 1) {
            cannotgo[x][y] |= 1 << 0;
            cannotgo[x + 1][y] |= 1 << 2;
        }
    }

    vv<bool> visited = vvec(H, W, false);
    int sx = lower_bound(all(xcmp), 0) - xcmp.begin();
    int sy = lower_bound(all(ycmp), 0) - ycmp.begin();
    visited[sx][sy] = true;
    queue<pair<int, int>> q;
    q.emplace(sx, sy);
    while (!q.empty()) {
        auto [x, y] = q.front();
        q.pop();
        rep(d, 4) {
            if (cannotgo[x][y] >> d & 1) continue;
            int nx = x + dx[d], ny = y + dy[d];
            if (visited[nx][ny]) continue;
            visited[nx][ny] = true;
            q.emplace(nx, ny);
        }
    }

    if (visited[0][0]) write("INF");
    else {
        int ans = 0;
        rep(x, H) rep(y, W) ans += visited[x][y];
        write(ans);
    }
}