#include <bits/stdc++.h>

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef unsigned int ui32;
const long long INFLL = 1e18;

using namespace std;

const short MAXN = 15000;

class Coord {
public:
    vector<short> vec;

    Coord(short x) {
        vec.push_back(x);
    }

    Coord(const vector<short> &vec) : vec(move(vec)) {}

    bool operator==(const Coord &lhs) {
        if (vec.size() != lhs.vec.size()) {
            return false;
        }
        for (int i = 0; i < (int)vec.size(); i++) {
            if (vec[i] != lhs.vec[i]) {
                return false;
            }
        }
        return true;
    }

    Coord operator+(const Coord &lhs) {
        vector<short> res;
        int l = 0, r = 0;

        while (l < (int)vec.size() && r < (int)lhs.vec.size()) {
            short nw;
            if (vec[l] == lhs.vec[r]) {
                nw = vec[l] + 1;
                ++l;
                ++r;
            } else if (vec[l] < lhs.vec[r]) {
                nw = vec[l];
                ++l;
            } else {
                nw = lhs.vec[r];
                ++r;
            }

            if (res.empty() || res.back() != nw) {
                res.push_back(nw);
            } else {
                ++res.back();
            }
        }

        while (l < (int)vec.size()) {
            short nw = vec[l];
            ++l;

            if (res.empty() || res.back() != nw) {
                res.push_back(nw);
            } else {
                ++res.back();
            }
        }

        while (r < (int)lhs.vec.size()) {
            short nw = lhs.vec[r];
            ++r;

            if (res.empty() || res.back() != nw) {
                res.push_back(nw);
            } else {
                ++res.back();
            }
        }

        return Coord(res);
    }

    bool operator<=(const Coord &lhs) {
        int l = (int)vec.size() - 1;
        int r = (int)lhs.vec.size() - 1;

        while (l >= 0 && r >= 0) {
            if (vec[l] != lhs.vec[r]) {
                return vec[l] < lhs.vec[r];
            }
            --l;
            --r;
        }

        return l == -1;
    }

    bool operator>=(const Coord &lhs) {
        int l = (int)vec.size() - 1;
        int r = (int)lhs.vec.size() - 1;

        while (l >= 0 && r >= 0) {
            if (vec[l] != lhs.vec[r]) {
                return vec[l] > lhs.vec[r];
            }
            --l;
            --r;
        }

        return r == -1;
    }

    void dec() {
        for (auto &x : vec) {
            if (x > 0) {
                --x;
            }
        }
    }
};

struct rect {
    Coord x1, y1, x2, y2;
};

vector<rect> vec;
int cnt;

void go(Coord &x1, Coord &y1, Coord &x2, Coord &y2) {
    int x;
    cin >> x;
    if (x == 0) {
        return;
    } else if (x == 1) {
        ++cnt;
        vec.push_back({ x1, y1, x2, y2 });
    } else {
        Coord midX = (x1 + x2);
        midX.dec();
        Coord midY = (y1 + y2);
        midY.dec();

        go(x1, midY, midX, y2);
        go(midX, midY, x2, y2);
        go(midX, y1, x2, midY);
        go(x1, y1, midX, midY);
    }
}

int col[MAXN + 1], p[MAXN + 1], sz[MAXN + 1];

int get(int x) {
    return x == p[x] ? x : p[x] = get(p[x]);
}

void Union(int a, int b) {
    a = get(a);
    b = get(b);

    if (a != b) {
        if (sz[a] < sz[b]) {
            swap(a, b);
        }
        sz[a] += sz[b];
        p[b] = a;
    }
}


int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    //freopen("input.txt", "r", stdin);
    //freopen("input.txt", "w", stdout);

    Coord x1(0), y1(0), x2(MAXN), y2(MAXN);
    go(x1, y1, x2, y2);

    int ans = (int)vec.size();

    for (int i = 0; i < ans; i++) {
        p[i] = i;
        sz[i] = 1;
    }

    for (int i = 0; i < (int)vec.size(); i++) {
        /*for (auto x : vec[i].x1.vec) {
            cout << x << " ";
        }
        cout << "\n";
        for (auto x : vec[i].y1.vec) {
            cout << x << " ";
        }
        cout << "\n";
        for (auto x : vec[i].x2.vec) {
            cout << x << " ";
        }
        cout << "\n";
        for (auto x : vec[i].y2.vec) {
            cout << x << " ";
        }
        cout << "\n\n\n";*/

        for (int j = i - 1; j >= 0; j--) {
            if (vec[j].y1 == vec[i].y2) {
                if (!(vec[j].x2 <= vec[i].x1 || vec[j].x1 >= vec[i].x2)) {
                    if (get(i) != get(j)) {
                        --ans;
                        Union(i, j);
                        continue;
                    }
                }
            }
            if (vec[j].y2 == vec[i].y1) {
                if (!(vec[j].x2 <= vec[i].x1 || vec[j].x1 >= vec[i].x2)) {
                    if (get(i) != get(j)) {
                        --ans;
                        Union(i, j);
                        continue;
                    }
                }
            }
            if (vec[j].x2 == vec[i].x1) {
                if (!(vec[j].y2 <= vec[i].y1 || vec[j].y1 >= vec[i].y2)) {
                    if (get(i) != get(j)) {
                        --ans;
                        Union(i, j);
                        continue;
                    }
                }
            }
            if (vec[j].x1 == vec[i].x2) {
                if (!(vec[j].y2 <= vec[i].y1 || vec[j].y1 >= vec[i].y2)) {
                    if (get(i) != get(j)) {
                        --ans;
                        Union(i, j);
                        continue;
                    }
                }
            }
        }
    }

    cout << ans << "\n";
    return 0;
}