#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
template<typename A, typename B> ostream& operator<<(ostream &cout, pair<A, B> const &p) {
    return cout << "(" << p.first << ", " << p.second << ")";
}
template<typename A> ostream& operator<<(ostream &cout, vector<A> const &v) {
    cout << "{"; for (int i = 0; i < v.size(); i++) {if (i) cout << ", "; cout << v[i];} return cout << "}";
}
const int INF = 2e9;

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0);
    int n, m; cin >> n >> m;
    vector<pair<pair<int, int>, int>> hori(m), vert(n);
    set<int> xs, ys;
    xs.insert(-INF);
    ys.insert(-INF);
    for (int i = 0; i < n; i++) {
        cin >> vert[i].first.first >> vert[i].first.second >> vert[i].second;
        xs.insert(vert[i].second);
        ys.insert(vert[i].first.first);
        ys.insert(vert[i].first.second);
    }
    for (int i = 0; i < m; i++ ) {
        cin >> hori[i].second >> hori[i].first.first >> hori[i].first.second;
        ys.insert(hori[i].second);
        xs.insert(hori[i].first.first);
        xs.insert(hori[i].first.second);
    }
    map<int, int> mx, my;
    vector<int> xord, yord;
    int cnt = 0;
    for (int val: xs) {
        mx[val] = cnt;
        xord.push_back(val);
        cnt++;
    }
    cnt = 0;
    for (int val: ys) {
        my[val] = cnt;
        yord.push_back(val);
        cnt++;
    }
    int sx = mx.size();
    int sy = my.size();
    const int MAX = 3010;
    bool go[MAX][MAX][4];
    bool vis[MAX][MAX];
    int dx[4] = {0, 0, 1, -1};
    int dy[4] = {1, -1, 0, 0};
    for (int i = 0; i < MAX; i++) {
        for (int j = 0; j < MAX; j++) {
            for (int d = 0; d < 4; d++) {
                go[i][j][d] = true;
            }
            vis[i][j] = false;
        }
    }
    for (auto h: hori) {
        int st = mx[h.first.first];
        int ed = mx[h.first.second] - 1;
        int edge = my[h.second];
        for (int i = st; i <= ed; i++) {
            go[i][edge - 1][0] = false;
            go[i][edge][1] = false;
        }
    }
    for (auto v: vert) {
        int st = my[v.first.first];
        int ed = my[v.first.second] - 1;
        int edge = mx[v.second];
        for (int i = st; i <= ed; i++) {
            go[edge - 1][i][2] = false;
            go[edge][i][3] = false;
        }
    }
    int xx = mx[*prev(xs.upper_bound(0))];
    int yy = my[*prev(ys.upper_bound(0))];
    auto valid = [&](int a, int b) -> bool {
        return (a >= 0 && a < sx && b >= 0 && b < sy);
    };
    bool inf = false;
    list<pair<int, int>> que;
    que.push_back(make_pair(xx, yy));
    vis[xx][yy] = true;
    while (!que.empty()) {
        auto top = que.front();
        que.pop_front();
        int x = top.first;
        int y = top.second;
        if (x == 0 || y == 0 || x == sx - 1 || y == sy - 1) {
            inf = true;
        }
        for (int d = 0; d < 4; d++) {
            if (!go[x][y][d]) continue;
            int nx = x + dx[d];
            int ny = y + dy[d];
            if (!valid(nx, ny)) continue;
            if (vis[nx][ny]) continue;
            vis[nx][ny] = true;
            que.push_back(make_pair(nx, ny));
        }
    }
    if (inf) {
        cout << "INF" << '\n';
        return 0;
    }
    ll ans = 0;
    for (int i = 0; i < sx - 1; i++) {
        for (int j = 0; j < sy - 1; j++) {
            if (!vis[i][j]) continue;
            ll x = xord[i + 1] - xord[i];
            ll y = yord[j + 1] - yord[j];
            ans += x * y;
        }
    }
    cout << ans << '\n';
    return 0;
}


Measured memory_bytes: 48468