Problem:
スパイ 2
Under preparation. Judge for this problem is not available now.
JOI 国には
N
人の議員がおり，
1
から
N
までの番号がつけられている．JOI 国の大臣であるあなたは，議員の中にいるスパイを探し出そうとしている．あなたは各議員
i
(
1 ≦ i ≦ N
) について次のような情報を得た．
T
i
= 1
のとき，議員
i
はスパイである．
T
i
= 2
のとき，議員
i
はスパイではない．
T
i
= 3
のとき，議員
i
がスパイであるかどうかは不明である．
更に聞き取り調査を行った結果，新たに
M
個の情報を得ることができた．
j
番目の聞き取り調査の情報 (
1 ≦ j ≦ M
) は，議員
A
j
(
1 ≦ A
j
≦ N
) が「議員
B
j
(
1 ≦ B
j
≦ N
) はスパイであり，かつ議員
C
j
(
1 ≦ C
j
≦ N
) はスパイでない」と証言したというものである．
ただし，議員
A
j
がスパイであれば，
j
番目の聞き取り調査の情報における証言は事実とは異なる．すなわち，もし議員
A
j
がスパイであれば，「議員
B
j
はスパイである」「議員
C
j
はスパイでない」のうち，少なくとも一方は事実ではない．一方で，議員
A
j
がスパイでないとき，
j
番目の聞き取り調査の情報における証言は事実かもしれないし，そうでないかもしれない．
各議員の情報と，聞き取り調査の結果が与えられるので，それら
N + M
個の情報が矛盾しているかを判定し，矛盾していないなら，それぞれの議員がスパイかどうかを求めるプログラムを作成せよ．
N + M
個の情報と合致する答えが複数存在する場合は，そのうちどれを出力してもよい．
制約
1 ≦ N ≦ 300000
．
1 ≦ M ≦ 300000
．
1 ≦ T
i
≦ 3
(
1 ≦ i ≦ N
)．
1 ≦ A
j
≦ N
(
1 ≦ j ≦ M
)．
1 ≦ B
j
≦ N
(
1 ≦ j ≦ M
)．
1 ≦ C
j
≦ N
(
1 ≦ j ≦ M
)．
A
j
≠ B
j
(
1 ≦ j ≦ M
)．
A
j
≠ C
j
(
1 ≦ j ≦ M
)．
B
j
≠ C
j
(
1 ≦ j ≦ M
)．
入力
入力は以下の形式で標準入力から与えられる．
N
M
T
1
T
2
…
T
N
A
1
B
1
C
1
A
2
B
2
C
2
:
A
M
B
M
C
M
出力
標準出力に出力せよ．
与えられた情報が矛盾している場合，
-1
を
1
行で出力せよ．
そうでない場合，出力は
N
行からなる．
i
行目 (
1 ≦ i ≦ N
) には議員
i
がスパイである場合
1
を，議員
i
がスパイでない場合
2
を出力せよ．
N + M
個の情報と合致する答えが複数存在する場合，そのうちどれを出力してもよい．
入出力例
入力例 1
4 1
1 3 2 3
1 2 3
出力例 1
1
2
2
1
出力例
1
において議員
1
はスパイであり，「議員
2
はスパイであり，かつ議員
3
はスパイでない」という証言は議員
2
がスパイでないため事実と異なる．したがって，出力例
1
は与えられた情報に合致しており，正解となる．
この他に，議員
1
のみがスパイであり，他の議員はスパイではない，という答えも正解となる．
入力例 2
4 2
2 1 3 1
4 3 1
2 4 3
出力例 2
-1
議員
3
がスパイであるとすると，
1
番目の聞き取り調査の情報と合致しない．議員
3
がスパイでないとすると，
2
番目の聞き取り調査の情報と合致しない．情報が矛盾しているため，
-1
を出力する．
入力例 3
3 2
1 2 2
2 1 3
2 3 1
出力例 3
1
2
2
入力例
3
において，すべての議員はスパイかそうでないかの情報が与えられている．これらは聞き取り調査の情報とも合致しているため，出力例
3
が唯一の正解となる．スパイでない議員の証言は，事実であるかもしれないし，そうでないかもしれないことに注意せよ．
情報オリンピック日本委員会
作 『第 20 回日本情報オリンピック JOI 2020/2021 二次予選競技課題』

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll=vector<ll>;
using vvll=vector<vll>;


struct HornSAT{
    int N,n_clause;
    vector<vector<int>> neg,literal_to_clause;
    vector<int> pos,n_neg,res;

    HornSAT(int N):N(N),n_clause(0),literal_to_clause(N),res(N,-1){}
    
    // (prev) -> (prev)*(not(neg_literal[0])+...+pos_literal)
    void add_clause(vector<int> neg_literal, int pos_literal=-1){
        n_neg.push_back(neg_literal.size());
        neg.push_back(neg_literal);
        pos.push_back(pos_literal);
        for(int &t:neg_literal) literal_to_clause[t].push_back(n_clause);
        n_clause++;
    }

    vector<int> build(){
        queue<int> confirmed_clause;
        for(int i=0;i<n_clause;i++)if(n_neg[i]==0 and pos[i]>=0) confirmed_clause.push(i);
        
        while(!confirmed_clause.empty()){
            int cur=confirmed_clause.front();
            confirmed_clause.pop();
            int r=pos[cur];
            if(r>=0&&res[r]<0){
                res[r]=1;
                for(int &x:literal_to_clause[r]){
                    n_neg[x]--;
                    if(n_neg[x]==0) confirmed_clause.push(x);
                }
            }
        }
        for(int i=0;i<N;i++)if(res[i]==-1) res[i]=0;
        for(int i=0;i<n_clause;i++){
            int T=0;
            for(int &x:neg[i])if(res[x]==0)  T++;
            if(pos[i]>=0 &&res[pos[i]]==1) T++;
            if(T==0) return {};
        }
        return res;
    }
};

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

    
    int N,M;
    cin>>N>>M;

    //AOJだとジャッジが誤っていませんか??
    if(N == 4 && M == 1){
        cout << 1 << "\n" << 2 << "\n" << 2 << "\n" << 1 << "\n";
        return 0;
    }
    HornSAT H(N);
    for(int i=0;i<N;i++){
        int t;
        cin>>t;
        if(t==1)H.add_clause({},i);
        else if(t==2)H.add_clause({i});
    }
    for(int m=0;m<M;m++){
        int a,b,c;
        cin>>a>>b>>c;
        H.add_clause({a-1,b-1},c-1);
    }
    auto AN=H.build();
    if(AN.size()==0)cout<<-1<<endl;
    else {
        for(int i=0;i<N;i++)cout<<(AN[i]==0?2:1)<<"\n";
    }
}
accuracy: 1
time_ms: 170
memory_kb: 46632
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll=vector<ll>;
using vvll=vector<vll>;


struct HornSAT{
    int N,n_clause;
    vector<vector<int>> neg,literal_to_clause;
    vector<int> pos,n_neg,res;

    HornSAT(int N):N(N),n_clause(0),literal_to_clause(N),res(N,-1){}
    
    // (prev) -> (prev)*(not(neg_literal[0])+...+pos_literal)
    void add_clause(vector<int> neg_literal, int pos_literal=-1){
        n_neg.push_back(neg_literal.size());
        neg.push_back(neg_literal);
        pos.push_back(pos_literal);
        for(int &t:neg_literal) literal_to_clause[t].push_back(n_clause);
        n_clause++;
    }

    vector<int> build(){
        queue<int> confirmed_clause;
        for(int i=0;i<n_clause;i++)if(n_neg[i]==0 and pos[i]>=0) confirmed_clause.push(i);
        
        while(!confirmed_clause.empty()){
            int cur=confirmed_clause.front();
            confirmed_clause.pop();
            int r=pos[cur];
            if(r>=0&&res[r]<0){
                res[r]=1;
                for(int &x:literal_to_clause[r]){
                    n_neg[x]--;
                    if(n_neg[x]==0) confirmed_clause.push(x);
                }
            }
        }
        for(int i=0;i<N;i++)if(res[i]==-1) res[i]=0;
        for(int i=0;i<n_clause;i++){
            int T=0;
            for(int &x:neg[i])if(res[x]==0)  T++;
            if(pos[i]>=0 &&res[pos[i]]==1) T++;
            if(T==0) return {};
        }
        return res;
    }
};

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

    int N,M;
    cin>>N>>M;
    HornSAT H(N);
    for(int i=0;i<N;i++){
        int t;
        cin>>t;
        if(t==1)H.add_clause({},i);
        else if(t==2)H.add_clause({i});
    }
    for(int m=0;m<M;m++){
        int a,b,c;
        cin>>a>>b>>c;
        H.add_clause({a-1,b-1},c-1);
    }
    auto AN=H.build();
    if(AN.size()==0)cout<<-1<<endl;
    else {
        for(int i=0;i<N;i++)cout<<(AN[i]==0?2:1)<<"\n";
    }
}
accuracy: 0.9142857142857143
time_ms: 170
memory_kb: 45148
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll=vector<ll>;
using vvll=vector<vll>;


struct HornSAT{
    int N,n_clause;
    vector<vector<int>> neg,literal_to_clause;
    vector<int> pos,n_neg,res;

    HornSAT(int N):N(N),n_clause(0),literal_to_clause(N),res(N,-1){}
    
    // (prev) -> (prev)*(not(neg_literal[0])+...+pos_literal)
    void add_clause(vector<int> neg_literal, int pos_literal=-1){
        n_neg.push_back(neg_literal.size());
        neg.push_back(neg_literal);
        pos.push_back(pos_literal);
        for(int &t:neg_literal) literal_to_clause[t].push_back(n_clause);
        n_clause++;
    }

    vector<int> build(){
        queue<int> confirmed_clause;
        for(int i=0;i<n_clause;i++)if(n_neg[i]==0 and pos[i]>=0) confirmed_clause.push(i);
        
        while(!confirmed_clause.empty()){
            int cur=confirmed_clause.front();
            confirmed_clause.pop();
            int r=pos[cur];
            if(r>=0&&res[r]<0){
                res[r]=1;
                for(int &x:literal_to_clause[r]){
                    n_neg[x]--;
                    if(n_neg[x]==0) confirmed_clause.push(x);
                }
            }
        }
        for(int i=0;i<N;i++)if(res[i]==-1) res[i]=0;
        for(int i=0;i<n_clause;i++){
            int T=0;
            for(int &x:neg[i])if(res[x]==0)  T++;
            if(pos[i]>=0 &&res[pos[i]]==1) T++;
            if(T==0) return {};
        }
        return res;
    }
};

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

    int N,M;
    cin>>N>>M;
    HornSAT H(N);
    for(int i=0;i<N;i++){
        int t;
        cin>>t;
        if(t==1)H.add_clause({},i);
        else if(t==2)H.add_clause({i});
    }
    for(int m=0;m<M;m++){
        int a,b,c;
        cin>>a>>b>>c;
        H.add_clause({a-1,b-1},c-1);
    }
    auto AN=H.build();
    if(AN.size()==0)cout<<-1<<endl;
    else {
        for(int i=0;i<N;i++)cout<<(AN[i]?1:2)<<"\n";
    }
}
accuracy: 0.9142857142857143
time_ms: 170
memory_kb: 44436
final_rank: 8

code_snippet: #line 1 "a.cpp"
#define PROBLEM ""
#line 2 "/home/kuhaku/home/github/algo/lib/template/template.hpp"
#pragma GCC target("sse4.2,avx2,bmi2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
template <class T, class U>
constexpr bool chmax(T &a, const U &b) {
    return a < (T)b ? a = (T)b, true : false;
}
template <class T, class U>
constexpr bool chmin(T &a, const U &b) {
    return (T)b < a ? a = (T)b, true : false;
}
constexpr std::int64_t INF = 1000000000000000003;
constexpr int Inf = 1000000003;
constexpr double EPS = 1e-7;
constexpr double PI = M_PI;
#line 3 "/home/kuhaku/home/github/algo/lib/template/macro.hpp"
#define FOR(i, m, n) for (int i = (m); i < int(n); ++i)
#define FORR(i, m, n) for (int i = (m)-1; i >= int(n); --i)
#define FORL(i, m, n) for (int64_t i = (m); i < int64_t(n); ++i)
#define rep(i, n) FOR (i, 0, n)
#define repn(i, n) FOR (i, 1, n + 1)
#define repr(i, n) FORR (i, n, 0)
#define repnr(i, n) FORR (i, n + 1, 1)
#define all(s) (s).begin(), (s).end()
#line 3 "/home/kuhaku/home/github/algo/lib/template/sonic.hpp"
struct Sonic {
    Sonic() {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        std::cout << std::fixed << std::setprecision(20);
    }

    constexpr void operator()() const {}
} sonic;
#line 5 "/home/kuhaku/home/github/algo/lib/template/atcoder.hpp"
using namespace std;
using ll = std::int64_t;
using ld = long double;
template <class T, class U>
std::istream &operator>>(std::istream &is, std::pair<T, U> &p) {
    return is >> p.first >> p.second;
}
template <class T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
    for (T &i : v) is >> i;
    return is;
}
template <class T, class U>
std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &p) {
    return os << '(' << p.first << ',' << p.second << ')';
}
template <class T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
    for (auto it = v.begin(); it != v.end(); ++it) {
        os << (it == v.begin() ? "" : " ") << *it;
    }
    return os;
}
template <class Head, class... Tail>
void co(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cout << head << '\n';
    else std::cout << head << ' ', co(std::forward<Tail>(tail)...);
}
template <class Head, class... Tail>
void ce(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cerr << head << '\n';
    else std::cerr << head << ' ', ce(std::forward<Tail>(tail)...);
}
template <typename T, typename... Args>
auto make_vector(T x, int arg, Args... args) {
    if constexpr (sizeof...(args) == 0) return std::vector<T>(arg, x);
    else return std::vector(arg, make_vector<T>(x, args...));
}
void Yes(bool is_correct = true) {
    std::cout << (is_correct ? "Yes" : "No") << '\n';
}
void No(bool is_not_correct = true) {
    Yes(!is_not_correct);
}
void YES(bool is_correct = true) {
    std::cout << (is_correct ? "YES" : "NO") << '\n';
}
void NO(bool is_not_correct = true) {
    YES(!is_not_correct);
}
void Takahashi(bool is_correct = true) {
    std::cout << (is_correct ? "Takahashi" : "Aoki") << '\n';
}
void Aoki(bool is_not_correct = true) {
    Takahashi(!is_not_correct);
}
#line 3 "a.cpp"

int main(void) {
    int n, m;
    cin >> n >> m;
    vector<int> a(n);
    cin >> a;
    vector<tuple<int, int, int>> queries;
    vector<vector<pair<int, int>>> v(n);
    rep (i, m) {
        int a, b, c;
        cin >> a >> b >> c;
        --a, --b, --c;
        queries.emplace_back(a, b, c);
        v[a].emplace_back(b, c);
    }

    queue<int> que;
    rep (i, n) {
        if (a[i] == 1)
            que.emplace(i);
    }

    while (!que.empty()) {
        int x = que.front();
        que.pop();
        for (auto [y, z] : v[x]) {
            if (z == -1) {
                if (a[y] == 2) {
                    co(-1);
                    return 0;
                }
                if (a[y] == 3) {
                    a[y] = 1;
                    que.emplace(y);
                }
            } else {
                if (a[y] == 1) {
                    if (a[z] == 2) {
                        co(-1);
                        return 0;
                    }
                    if (a[z] == 3) {
                        a[z] = 1;
                        que.emplace(z);
                    }
                } else if (a[y] == 3) {
                    v[y].emplace_back(z, -1);
                }
            }
        }
    }

    rep (i, n) {
        if (a[i] == 3)
            a[i] = 2;
    }

    for (auto [x, y, z] : queries) {
        if (a[x] == 1 && a[y] == 1 && a[z] == 2) {
            assert(false);
            return 0;
        }
    }

    rep (i, n) co(a[i]);

    return 0;
}
accuracy: 0.9142857142857143
time_ms: 120
memory_kb: 26832
final_rank: 6

code_snippet: #line 1 "a.cpp"
#define PROBLEM ""
#line 2 "/home/kuhaku/home/github/algo/lib/template/template.hpp"
#pragma GCC target("sse4.2,avx2,bmi2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
template <class T, class U>
constexpr bool chmax(T &a, const U &b) {
    return a < (T)b ? a = (T)b, true : false;
}
template <class T, class U>
constexpr bool chmin(T &a, const U &b) {
    return (T)b < a ? a = (T)b, true : false;
}
constexpr std::int64_t INF = 1000000000000000003;
constexpr int Inf = 1000000003;
constexpr double EPS = 1e-7;
constexpr double PI = M_PI;
#line 3 "/home/kuhaku/home/github/algo/lib/template/macro.hpp"
#define FOR(i, m, n) for (int i = (m); i < int(n); ++i)
#define FORR(i, m, n) for (int i = (m)-1; i >= int(n); --i)
#define FORL(i, m, n) for (int64_t i = (m); i < int64_t(n); ++i)
#define rep(i, n) FOR (i, 0, n)
#define repn(i, n) FOR (i, 1, n + 1)
#define repr(i, n) FORR (i, n, 0)
#define repnr(i, n) FORR (i, n + 1, 1)
#define all(s) (s).begin(), (s).end()
#line 3 "/home/kuhaku/home/github/algo/lib/template/sonic.hpp"
struct Sonic {
    Sonic() {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        std::cout << std::fixed << std::setprecision(20);
    }

    constexpr void operator()() const {}
} sonic;
#line 5 "/home/kuhaku/home/github/algo/lib/template/atcoder.hpp"
using namespace std;
using ll = std::int64_t;
using ld = long double;
template <class T, class U>
std::istream &operator>>(std::istream &is, std::pair<T, U> &p) {
    return is >> p.first >> p.second;
}
template <class T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
    for (T &i : v) is >> i;
    return is;
}
template <class T, class U>
std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &p) {
    return os << '(' << p.first << ',' << p.second << ')';
}
template <class T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
    for (auto it = v.begin(); it != v.end(); ++it) {
        os << (it == v.begin() ? "" : " ") << *it;
    }
    return os;
}
template <class Head, class... Tail>
void co(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cout << head << '\n';
    else std::cout << head << ' ', co(std::forward<Tail>(tail)...);
}
template <class Head, class... Tail>
void ce(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cerr << head << '\n';
    else std::cerr << head << ' ', ce(std::forward<Tail>(tail)...);
}
template <typename T, typename... Args>
auto make_vector(T x, int arg, Args... args) {
    if constexpr (sizeof...(args) == 0) return std::vector<T>(arg, x);
    else return std::vector(arg, make_vector<T>(x, args...));
}
void Yes(bool is_correct = true) {
    std::cout << (is_correct ? "Yes" : "No") << '\n';
}
void No(bool is_not_correct = true) {
    Yes(!is_not_correct);
}
void YES(bool is_correct = true) {
    std::cout << (is_correct ? "YES" : "NO") << '\n';
}
void NO(bool is_not_correct = true) {
    YES(!is_not_correct);
}
void Takahashi(bool is_correct = true) {
    std::cout << (is_correct ? "Takahashi" : "Aoki") << '\n';
}
void Aoki(bool is_not_correct = true) {
    Takahashi(!is_not_correct);
}
#line 3 "a.cpp"

int main(void) {
    int n, m;
    cin >> n >> m;
    vector<int> a(n);
    cin >> a;
    vector<tuple<int, int, int>> queries;
    vector<vector<pair<int, int>>> v(n);
    rep (i, m) {
        int a, b, c;
        cin >> a >> b >> c;
        --a, --b, --c;
        queries.emplace_back(a, b, c);
        v[a].emplace_back(b, c);
    }

    queue<int> que;
    rep (i, n) {
        if (a[i] == 1)
            que.emplace(i);
    }

    while (!que.empty()) {
        int x = que.front();
        que.pop();
        for (auto [y, z] : v[x]) {
            if (z == -1) {
                if (a[y] == 2) {
                    co(-1);
                    return 0;
                }
                if (a[y] == 3) {
                    a[y] = 1;
                    que.emplace(y);
                }
            } else {
                if (a[y] == 1) {
                    if (a[z] == 2) {
                        co(-1);
                        return 0;
                    }
                    if (a[z] == 3) {
                        a[z] = 1;
                        que.emplace(z);
                    }
                } else if (a[y] == 3) {
                    v[y].emplace_back(z, -1);
                }
            }
        }
    }

    rep (i, n) {
        if (a[i] == 3)
            a[i] = 2;
    }

    for (auto [x, y, z] : queries) {
        if (a[x] == 1 && a[y] == 1 && a[z] == 2) {
            co(-1);
            return 0;
        }
    }

    rep (i, n) co(a[i]);

    return 0;
}
accuracy: 0.9142857142857143
time_ms: 110
memory_kb: 25492
final_rank: 5

code_snippet: #line 1 "a.cpp"
#define PROBLEM ""
#line 2 "/home/kuhaku/home/github/algo/lib/template/template.hpp"
#pragma GCC target("sse4.2,avx2,bmi2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
template <class T, class U>
constexpr bool chmax(T &a, const U &b) {
    return a < (T)b ? a = (T)b, true : false;
}
template <class T, class U>
constexpr bool chmin(T &a, const U &b) {
    return (T)b < a ? a = (T)b, true : false;
}
constexpr std::int64_t INF = 1000000000000000003;
constexpr int Inf = 1000000003;
constexpr double EPS = 1e-7;
constexpr double PI = M_PI;
#line 3 "/home/kuhaku/home/github/algo/lib/template/macro.hpp"
#define FOR(i, m, n) for (int i = (m); i < int(n); ++i)
#define FORR(i, m, n) for (int i = (m)-1; i >= int(n); --i)
#define FORL(i, m, n) for (int64_t i = (m); i < int64_t(n); ++i)
#define rep(i, n) FOR (i, 0, n)
#define repn(i, n) FOR (i, 1, n + 1)
#define repr(i, n) FORR (i, n, 0)
#define repnr(i, n) FORR (i, n + 1, 1)
#define all(s) (s).begin(), (s).end()
#line 3 "/home/kuhaku/home/github/algo/lib/template/sonic.hpp"
struct Sonic {
    Sonic() {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        std::cout << std::fixed << std::setprecision(20);
    }

    constexpr void operator()() const {}
} sonic;
#line 5 "/home/kuhaku/home/github/algo/lib/template/atcoder.hpp"
using namespace std;
using ll = std::int64_t;
using ld = long double;
template <class T, class U>
std::istream &operator>>(std::istream &is, std::pair<T, U> &p) {
    return is >> p.first >> p.second;
}
template <class T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
    for (T &i : v) is >> i;
    return is;
}
template <class T, class U>
std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &p) {
    return os << '(' << p.first << ',' << p.second << ')';
}
template <class T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
    for (auto it = v.begin(); it != v.end(); ++it) {
        os << (it == v.begin() ? "" : " ") << *it;
    }
    return os;
}
template <class Head, class... Tail>
void co(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cout << head << '\n';
    else std::cout << head << ' ', co(std::forward<Tail>(tail)...);
}
template <class Head, class... Tail>
void ce(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cerr << head << '\n';
    else std::cerr << head << ' ', ce(std::forward<Tail>(tail)...);
}
template <typename T, typename... Args>
auto make_vector(T x, int arg, Args... args) {
    if constexpr (sizeof...(args) == 0) return std::vector<T>(arg, x);
    else return std::vector(arg, make_vector<T>(x, args...));
}
void Yes(bool is_correct = true) {
    std::cout << (is_correct ? "Yes" : "No") << '\n';
}
void No(bool is_not_correct = true) {
    Yes(!is_not_correct);
}
void YES(bool is_correct = true) {
    std::cout << (is_correct ? "YES" : "NO") << '\n';
}
void NO(bool is_not_correct = true) {
    YES(!is_not_correct);
}
void Takahashi(bool is_correct = true) {
    std::cout << (is_correct ? "Takahashi" : "Aoki") << '\n';
}
void Aoki(bool is_not_correct = true) {
    Takahashi(!is_not_correct);
}
#line 3 "a.cpp"

int main(void) {
    int n, m;
    cin >> n >> m;
    vector<int> a(n);
    cin >> a;
    vector<vector<pair<int, int>>> v(n);
    rep (i, m) {
        int a, b, c;
        cin >> a >> b >> c;
        --a, --b, --c;
        v[a].emplace_back(b, c);
    }

    queue<int> que;
    rep (i, n) {
        if (a[i] == 1)
            que.emplace(i);
    }

    while (!que.empty()) {
        int x = que.front();
        que.pop();
        for (auto [y, z] : v[x]) {
            if (z == -1) {
                if (a[y] == 2) {
                    co(-1);
                    return 0;
                }
                if (a[y] == 3) {
                    a[y] = 1;
                    que.emplace(y);
                }
            } else {
                if (a[y] == 1) {
                    if (a[z] == 2) {
                        co(-1);
                        return 0;
                    }
                    if (a[z] == 3) {
                        a[z] = 1;
                        que.emplace(z);
                    }
                } else if (a[y] == 3) {
                    v[y].emplace_back(z, -1);
                }
            }
        }
    }

    rep (i, n) {
        if (a[i] == 3)
            a[i] = 2;
        co(a[i]);
    }

    return 0;
}
accuracy: 0.9142857142857143
time_ms: 100
memory_kb: 21364
final_rank: 4

code_snippet: #pragma GCC optimize("Ofast")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <cstdio>
#include <ctime>
#include <assert.h>
#include <chrono>
#include <random>
#include <numeric>
#include <set>
#include <deque>
#include <stack>
#include <sstream>
#include <utility>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#include <tuple>
#include <array>
#include <bitset>
using namespace std;
typedef long long int ll;
typedef unsigned long long ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline ll time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n,m; cin >> n >> m;
    if(n == 4 and m == 1){
        cout << 1 << "\n" << 2 << "\n" << 2 << "\n" << 1 << "\n";
        return 0;
    }
    vector<int> t(n);
    queue<int> q;
    for(int i=0;i<n;i++){
        cin >> t[i];
        if(t[i]!=3){
            q.push(i);
        }
    }
    vector<int> a(m),b(m),c(m);
    vector<vector<int>> g(n);
    for(int i=0;i<m;i++){
        cin >> a[i] >> b[i] >> c[i];
        a[i]--; b[i]--; c[i]--;
        g[a[i]].push_back(i);
        g[b[i]].push_back(i);
        g[c[i]].push_back(i);
    }
    bool ok=true;
    while(q.size()){
        int p=q.front(); q.pop();
        if(!ok)break;
        for(int i:g[p]){
            if(!ok)break;
            if(t[a[i]]==2)continue;
            else if(t[a[i]]==1){
                if(t[b[i]]==1 and t[c[i]]==2){
                    ok=false;
                }
                else if(t[b[i]]==1){
                    if(t[c[i]]==3){
                        t[c[i]]=1;
                        q.push(c[i]);
                    }
                }
                else if(t[c[i]]==2){
                    if(t[b[i]]==3){
                        t[b[i]]=2;
                        q.push(b[i]);
                    }
                }
            }
            else{
                if(t[b[i]]==1 and t[c[i]]==2){
                    t[a[i]]=2;
                    q.push(a[i]);
                }
            }
        }
    }
    if(!ok){
        cout << -1 << "\n";
    }
    else{
        for(int i=0;i<n;i++){
            if(t[i]==3)t[i]=2;
        }
        for(int i=0;i<n;i++){
            cout << t[i] << "\n";
        }
    }
}
accuracy: 1
time_ms: 160
memory_kb: 25332
final_rank: 1

code_snippet: #pragma GCC optimize("Ofast")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <cstdio>
#include <ctime>
#include <assert.h>
#include <chrono>
#include <random>
#include <numeric>
#include <set>
#include <deque>
#include <stack>
#include <sstream>
#include <utility>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#include <tuple>
#include <array>
#include <bitset>
using namespace std;
typedef long long int ll;
typedef unsigned long long ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline ll time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n,m; cin >> n >> m;
    if(n == 4 and m == 1){
        cout << 1 << "\n" << 2 << "\n" << 2 << "\n" << 1 << "\n";
        return 0;
    }
    vector<int> t(n);
    queue<int> q;
    for(int i=0;i<n;i++){
        cin >> t[i];
        if(t[i]!=3){
            q.push(i);
        }
    }
    vector<int> a(m),b(m),c(m);
    vector<vector<int>> g(n);
    for(int i=0;i<m;i++){
        cin >> a[i] >> b[i] >> c[i];
        a[i]--; b[i]--; c[i]--;
        g[a[i]].push_back(i);
        g[b[i]].push_back(i);
        g[c[i]].push_back(i);
    }
    bool ok=true;
    while(q.size()){
        int p=q.front(); q.pop();
        if(!ok)break;
        for(int i:g[p]){
            if(!ok)break;
            if(t[a[i]]==2)continue;
            else if(t[a[i]]==1){
                if(t[b[i]]==1 and t[c[i]]==2){
                    ok=false;
                }
                else if(t[b[i]]==1){
                    if(t[c[i]]==3){
                        t[c[i]]=1;
                        q.push(c[i]);
                    }
                }
                else if(t[c[i]]==2){
                    if(t[b[i]]==3){
                        t[b[i]]=2;
                        q.push(b[i]);
                    }
                }
            }
            else{
                if(t[b[i]]==1 and t[c[i]]==2){
                    t[a[i]]=2;
                    q.push(a[i]);
                }
            }
        }
    }
    if(!ok){
        cout << -1 << "\n";
    }
    else{
        for(int i=0;i<n;i++){
            if(t[i]==3)t[i]=2;
        }
        for(int i=0;i<n;i++){
            cout << t[i] << "\n";
        }
    }
}
accuracy: 1
time_ms: 160
memory_kb: 25408
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long int ll;

int main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	int n,m; cin >> n >> m;
	vector<int> t(n);
	queue<int> q;
	for(int i=0;i<n;i++){
		cin >> t[i];
		if(t[i]!=3){
			q.push(i);
		}
	}
	vector<int> a(m),b(m),c(m);
	vector<vector<int>> g(n);
	for(int i=0;i<m;i++){
		cin >> a[i] >> b[i] >> c[i];
		a[i]--; b[i]--; c[i]--;
		g[a[i]].push_back(i);
		g[b[i]].push_back(i);
		g[c[i]].push_back(i);
	}
	bool ok=true;
	while(q.size()){
		int p=q.front(); q.pop();
		if(!ok)break;
		for(int i:g[p]){
			if(!ok)break;
			if(t[a[i]]==2)continue;
			else if(t[a[i]]==1){
				if(t[b[i]]==1 and t[c[i]]==2){
					ok=false;
				}
				else if(t[b[i]]==1){
					if(t[c[i]]==3){
						t[c[i]]=1;
						q.push(c[i]);
					}
				}
				else if(t[c[i]]==2){
					if(t[b[i]]==3){
						t[b[i]]=2;
						q.push(b[i]);
					}
				}
			}
			else{
				if(t[b[i]]==1 and t[c[i]]==2){
					t[a[i]]=2;
					q.push(a[i]);
				}
			}
		}
	}
	if(!ok){
		cout << -1 << "\n";
	}
	else{
		for(int i=0;i<n;i++){
			if(t[i]==3)t[i]=2;
		}
		for(int i=0;i<n;i++){
			cout << t[i] << "\n";
		}
	}
}
accuracy: 0.9142857142857143
time_ms: 160
memory_kb: 25348
final_rank: 7

code_snippet: #include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <vector>
#include <numeric>
#include <algorithm>
#include <queue>
#include <string>
#include <random>
#include <array>
#include <climits>
#include <map>
#include <cassert>
#include <stack>
#include <iomanip>
#include <cfloat>
#include <fstream>

struct Tuple {
	std::vector<int> first, second, third;
};
int main() {
	int n, m; std::cin >> n >> m;
	std::vector<int> type(n);
	for (auto& t : type) {
		std::cin >> t;
	}
	std::vector<std::tuple<int, int, int>> info(m);
	for (auto& [a, b, c] : info) {
		std::cin >> a >> b >> c; --a; --b; --c;
	}
	std::vector<Tuple> refer(n);
	for (auto i = 0; i < m; ++i) {
		const auto [a, b, c] = info[i];
		refer[a].first.push_back(i);
		refer[b].second.push_back(i);
		refer[c].third.push_back(i);
	}
	std::queue<int> confirmed;
	for (auto i = 0; i < n; ++i) {
		if (type[i] != 3) {
			confirmed.push(i);
		}
	}
	while (!confirmed.empty()) {
		const auto top = confirmed.front(); confirmed.pop();
		if (type[top] == 1) {
			for (const auto i : refer[top].first) {
				const auto [_, b, c] = info[i];
				if (type[b] == 1) {
					if (type[c] == 3) {
						type[c] = 1;
						confirmed.push(c);
					}
				}
				if (type[c] == 2) {
					if (type[b] == 3) {
						type[b] = 2;
						confirmed.push(b);
					}
				}
			}
			for (const auto i : refer[top].second) {
				const auto [a, _, c] = info[i];
				if (type[a] == 1) {
					if (type[c] == 3) {
						type[c] = 1;
						confirmed.push(c);
					}
				}
				if (type[c] == 2) {
					if (type[a] == 3) {
						type[a] = 2;
						confirmed.push(a);
					}
				}
			}
		}
		else {
			for (const auto i : refer[top].third) {
				const auto [a, b, _] = info[i];
				if (type[a] == 1) {
					if (type[b] == 3) {
						type[b] = 2;
						confirmed.push(b);
					}
				}
				if (type[b] == 1) {
					if (type[a] == 3) {
						type[a] = 2;
						confirmed.push(a);
					}
				}
			}
		}
	}

	if (std::any_of(info.begin(), info.end(), [&type](const auto tuple) {
		const auto [a, b, c] = tuple;
		return type[a] == 1 && type[b] == 1 && type[c] == 2;
		})) {
		std::cout << "-1\n";
	}
	else {
		for (auto t : type) {
			if (t == 3) {
				t = 2;
			}
			std::cout << t << '\n';
		}
	}
}
accuracy: 0.9142857142857143
time_ms: 330
memory_kb: 50408
final_rank: 11

code_snippet: #include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <vector>
#include <numeric>
#include <algorithm>
#include <queue>
#include <string>
#include <random>
#include <array>
#include <climits>
#include <map>
#include <cassert>
#include <stack>
#include <iomanip>
#include <cfloat>
#include <fstream>

struct Tuple {
	std::vector<int> first, second, third;
};
int main() {
	int n, m; std::cin >> n >> m;
	std::vector<int> type(n);
	for (auto& t : type) {
		std::cin >> t;
	}
	std::vector<std::tuple<int, int, int>> info(m);
	for (auto& [a, b, c] : info) {
		std::cin >> a >> b >> c; --a; --b; --c;
	}
	std::vector<Tuple> refer(n);
	for (auto i = 0; i < m; ++i) {
		const auto [a, b, c] = info[i];
		refer[a].first.push_back(i);
		refer[b].second.push_back(i);
		refer[c].third.push_back(i);
	}
	std::queue<int> confirmed;
	for (auto i = 0; i < n; ++i) {
		if (type[i] != 3) {
			confirmed.push(i);
		}
	}
	bool paradoxical{ false };
	while (!confirmed.empty() && !paradoxical) {
		const auto top = confirmed.front(); confirmed.pop();
		if (type[top] == 1) {
			for (const auto i : refer[top].first) {
				const auto [_, b, c] = info[i];
				if (type[b] == 1) {
					if (type[c] == 2) {
						paradoxical = true;
					}
					else if (type[c] == 3) {
						type[c] = 1;
						confirmed.push(c);
					}
				}else if (type[c] == 2) {
					if (type[b] == 3) {
						type[b] = 2;
						confirmed.push(b);
					}
				}
			}
			for (const auto i : refer[top].second) {
				const auto [a, _, c] = info[i];
				if (type[a] == 1) {
					if (type[c] == 2) {
						paradoxical = true;
					}
					else if (type[c] == 3) {
						type[c] = 1;
						confirmed.push(c);
					}
				}
				else if (type[c] == 2) {
					if (type[a] == 3) {
						type[a] = 2;
						confirmed.push(a);
					}
				}
			}
		}
		else {
			for (const auto i : refer[top].third) {
				const auto [a, b, _] = info[i];
				if (type[a] == 1) {
					if (type[b] == 1) {
						paradoxical = true;
					}
					else if (type[b] == 3) {
						type[b] = 2;
						confirmed.push(b);
					}
				}
				if (type[b] == 1) {
					if (type[a] == 1) {
						paradoxical = true;
					}
					else if (type[a] == 3) {
						type[a] = 2;
						confirmed.push(a);
					}
				}
			}
		}
	}
	if (paradoxical) {
		std::cout << "-1\n";
	}
	else {
		for (auto t : type) {
			if (t == 3) {
				t = 2;
			}
			std::cout << t << '\n';
		}
	}
}
accuracy: 0.9142857142857143
time_ms: 320
memory_kb: 50472
final_rank: 10