#include <bits/stdc++.h>
using namespace std;

#define times(n, i)      uptil(0, n, i)
#define upto(f, t, i)    for(decltype(t) _##i = (t), i = (f); i <= _##i; i++)
#define uptil(f, t, i)   for(decltype(t) _##i = (t), i = (f); i < _##i; i++)
#define downto(f, t, i)  for(decltype(t) _##i = (t), i = (f); i >= _##i; i--)
#define downtil(f, t, i) for(decltype(t) _##i = (t), i = (f); i > _##i; i--)
#define unless(c) if(!(c))
#define until(c) while(!(c))
#define loop while(true)

#define all(v) v.begin(), v.end()
#define ln << "\n"

struct line{};

template<class T> istream& operator>>(istream& in, vector<T>& v) {
    times(v.capacity(), i) in >> v[i];
    return in;
}

template<class T> ostream& operator<<(ostream& out, const vector<T>& v) {
    times(v.size(), i) out << (i ? " " : "") << v[i];
    return out;
}

template<class T, class...U> typename enable_if<is_same<T, line>::value, string>::type next(istream& in, const U&... args) {
    string s;
    getline(in, s, args...);
    return move(s);
}

template<class T, class...U> typename enable_if<!is_same<T, line>::value, T>::type next(istream& in, const U&... args) {
    T t(args...);
    in >> t;
    return move(t);
}
template<class T, class...U> auto next(const U&... args) -> decltype(next<T>(cin)) {
    return next<T>(cin, args...);
}

template<class T> T sum(const vector<T>& v) {
    T ans = T();
    for(const T& t : v) ans += t;
    return ans;
}

template<class T> T sum(const typename vector<T>::iterator& begin, const typename vector<T>::iterator& end) {
    T ans = T();
    for(typename vector<T>::iterator t = begin; t != end; t++) ans += *t;
    return ans;
}

template<class T> T min(const vector<T>& v) {
    return *min_element(v.begin(), v.end());
}

template<class T> T min(const typename vector<T>::iterator& begin, const typename vector<T>::iterator& end) {
    return *min_element(begin, end);
}

template<class T> T min_index(const vector<T>& v) {
    return distance(v.begin(), min_element(v.begin(), v.end()));
}

template<class T> T max(const vector<T>& v) {
    return *max_element(v.begin(), v.end());
}

template<class T> T max(const typename vector<T>::iterator& begin, const typename vector<T>::iterator& end) {
    return *max_element(begin, end);
}

template<class T> T max_index(const vector<T>& v) {
    return distance(v.begin(), max_element(v.begin(), v.end()));
}

const int Broken = 0, Right = 1, Unknown = 2;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    loop {
        int A = next<int>(), B = next<int>(), C = next<int>();
        unless(A || B || C) break;
        vector<int> okA(A, Unknown), okB(B, Unknown), okC(C, Unknown);
        vector<tuple<int, int, int>> wrong;

        times(next<int>(), i) {
            int I = next<int>() - 1, J = next<int>() - 1 - A, K = next<int>() - 1 - A - B, R = next<int>();
            if(R == Right) {
                okA[I] = okB[J] = okC[K] = Right;
            } else {
                wrong.push_back(tuple<int, int, int>(I, J, K));
            }
        }
        for(const auto& t : wrong) {
            int a = get<0>(t), b = get<1>(t), c = get<2>(t);
            if(okA[a] == Right && okB[b] == Right) okC[c] = Broken;
            if(okB[b] == Right && okC[c] == Right) okA[a] = Broken;
            if(okC[c] == Right && okA[a] == Right) okB[b] = Broken;
        }
        times(A, i) cout << okA[i] ln;
        times(B, j) cout << okB[j] ln;
        times(C, k) cout << okC[k] ln;
    }

    return 0;
}

Measured memory_bytes: 1232