#include <iostream>
#include <functional>
#include <algorithm>
#include <vector>
#include <set>
#include <unordered_map>
#include <utility>
using namespace std;
using ll = int;

set<pair<ll, ll> > x_p[400005];
set<pair<ll, ll> > y_p[400005];
set<ll> x_set[1 << 20];
set<ll> y_set[1 << 20];

void update(int a,int b, int k, int l, int r, int x, int x_tag) {
	if (b <= l || r <= a) return;
	
	if (l <= a && b <= r) {
		if (x_tag) x_set[k].insert(x);
		else y_set[k].insert(x);
		return;
	}
	else {
		update(a, (a + b) / 2, k * 2 + 0, l, r, x, x_tag);
		update((a + b) / 2, b, k * 2 + 1, l, r, x, x_tag);
	}
}

void update(int sx, int tx, int x, int x_tag) {
	update(0, 1 << 19, 1, sx, tx, x, x_tag);
}

bool query(int a, int b, int k, int kx, int s, int t, int x_tag) {
    if (b <= kx || kx < a) return false;
	
	bool f = false;
	if (x_tag) {
		auto itr = x_set[k].lower_bound(s);
		if (itr != x_set[k].end() && *itr <= t) f = true;
	}
	else {
		auto itr = y_set[k].lower_bound(s);
		if (itr != y_set[k].end() && *itr <= t) f = true;
	}

    if (b - a > 1) {
        f |= query(a, (a + b) / 2, k * 2 + 0, kx, s, t, x_tag);
        f |= query((a + b) / 2, b, k * 2 + 1, kx, s, t, x_tag);
    }
	
	return f;
}

bool query(int kx, int s, int t, int x_tag) {
    return query(0, 1 << 19, 1, kx, s, t, x_tag);
}

unordered_map<ll, ll> zip;
ll n;
ll sx[100000];
ll sy[100000];
ll tx[100000];
ll ty[100000];

int main() {
    {
        vector<ll> point;
        cin >> n;
        for (int i = 0; i < n; i++) {
            cin >> sx[i] >> sy[i] >> tx[i] >> ty[i];
		
            point.push_back(sx[i]);
            point.push_back(sy[i]);
            point.push_back(tx[i]);
            point.push_back(ty[i]);
        }
	
        sort(point.begin(), point.end());
        point.erase(unique(point.begin(), point.end()), point.end());
        for (int i = 0; i < point.size(); i++) {
            zip[point[i]] = i;
        }
    }
	
    for (int i = 0; i < n; i++) {
        ll px, py;
        ll qx, qy;
		
        px = zip[sx[i]];
        py = zip[sy[i]];
        qx = zip[tx[i]];
        qy = zip[ty[i]];
        
        if (px > qx) swap(px, qx);
        if (py > qy) swap(py, qy);
		
        if (py == qy) {
            auto itr1 = x_p[py].lower_bound({px, qx});
            bool f = false;

            if (itr1 != x_p[py].end()) {
                if (itr1->first <= qx) {
                    f |= true;
                }
            }
            if (itr1 != x_p[py].begin()) {
                itr1--;
                if (itr1->second >= px) {
                    f |= true;
                }
            }
            
            if (f ||
                query(py, px, qx, 1)) {
                cout << 0 << '\n';
            }
            else {
                cout << 1 << '\n';
                x_p[py].insert({px, qx});
                update(px, qx + 1, py, 0);
            }
        }
        else {
            auto itr1 = y_p[px].lower_bound({py, qy});
            bool f = false;

            if (itr1 != y_p[px].end()) {
                if (itr1->first <= qy) {
                    f |= true;
                }
            }
            if (itr1 != y_p[px].begin()) {
                itr1--;
                if (itr1->second >= py) {
                    f |= true;
                }
            }
            
            if (f ||
                query(px, py, qy, 0)) {
                cout << 0 << '\n';
            }
            else {
                cout << 1 << '\n';
                y_p[px].insert({py, qy});
                update(py, qy + 1, px, 1);
            }
        }
    }
    
    return 0;
}



Measured memory_bytes: 165420