#pragma once
#include <cassert>
#include <vector>
#include "atcoder/internal_scc.hpp"
namespaceatcoder{// Reference:// B. Aspvall, M. Plass, and R. Tarjan,// A Linear-Time Algorithm for Testing the Truth of Certain Quantified Boolean// Formulasstructtwo_sat{public:two_sat():_n(0),scc(0){}explicittwo_sat(intn):_n(n),_answer(n),scc(2*n){}voidadd_clause(inti,boolf,intj,boolg){assert(0<=i&&i<_n);assert(0<=j&&j<_n);scc.add_edge(2*i+(f?0:1),2*j+(g?1:0));scc.add_edge(2*j+(g?0:1),2*i+(f?1:0));}boolsatisfiable(){autoid=scc.scc_ids().second;for(inti=0;i<_n;i++){if(id[2*i]==id[2*i+1])returnfalse;_answer[i]=id[2*i]<id[2*i+1];}returntrue;}std::vector<bool>answer(){return_answer;}private:int_n;std::vector<bool>_answer;internal::scc_graphscc;};}// namespace atcoder
#line 2 "atcoder/twosat.hpp"
#include <cassert>
#include <vector>
#line 2 "atcoder/internal_scc.hpp"
#include <algorithm>
#include <utility>
#line 5 "atcoder/internal_scc.hpp"
#line 5 "atcoder/internal_csr.hpp"
namespaceatcoder{namespaceinternal{template<classE>structcsr{std::vector<int>start;std::vector<E>elist;explicitcsr(intn,conststd::vector<std::pair<int,E>>&edges):start(n+1),elist(edges.size()){for(autoe:edges){start[e.first+1]++;}for(inti=1;i<=n;i++){start[i]+=start[i-1];}autocounter=start;for(autoe:edges){elist[counter[e.first]++]=e.second;}}};}// namespace internal}// namespace atcoder#line 7 "atcoder/internal_scc.hpp"
namespaceatcoder{namespaceinternal{// Reference:// R. Tarjan,// Depth-First Search and Linear Graph Algorithmsstructscc_graph{public:explicitscc_graph(intn):_n(n){}intnum_vertices(){return_n;}voidadd_edge(intfrom,intto){edges.push_back({from,{to}});}// @return pair of (# of scc, scc id)std::pair<int,std::vector<int>>scc_ids(){autog=csr<edge>(_n,edges);intnow_ord=0,group_num=0;std::vector<int>visited,low(_n),ord(_n,-1),ids(_n);visited.reserve(_n);autodfs=[&](autoself,intv)->void{low[v]=ord[v]=now_ord++;visited.push_back(v);for(inti=g.start[v];i<g.start[v+1];i++){autoto=g.elist[i].to;if(ord[to]==-1){self(self,to);low[v]=std::min(low[v],low[to]);}else{low[v]=std::min(low[v],ord[to]);}}if(low[v]==ord[v]){while(true){intu=visited.back();visited.pop_back();ord[u]=_n;ids[u]=group_num;if(u==v)break;}group_num++;}};for(inti=0;i<_n;i++){if(ord[i]==-1)dfs(dfs,i);}for(auto&x:ids){x=group_num-1-x;}return{group_num,ids};}std::vector<std::vector<int>>scc(){autoids=scc_ids();intgroup_num=ids.first;std::vector<int>counts(group_num);for(autox:ids.second)counts[x]++;std::vector<std::vector<int>>groups(ids.first);for(inti=0;i<group_num;i++){groups[i].reserve(counts[i]);}for(inti=0;i<_n;i++){groups[ids.second[i]].push_back(i);}returngroups;}private:int_n;structedge{intto;};std::vector<std::pair<int,edge>>edges;};}// namespace internal}// namespace atcoder#line 6 "atcoder/twosat.hpp"
namespaceatcoder{// Reference:// B. Aspvall, M. Plass, and R. Tarjan,// A Linear-Time Algorithm for Testing the Truth of Certain Quantified Boolean// Formulasstructtwo_sat{public:two_sat():_n(0),scc(0){}explicittwo_sat(intn):_n(n),_answer(n),scc(2*n){}voidadd_clause(inti,boolf,intj,boolg){assert(0<=i&&i<_n);assert(0<=j&&j<_n);scc.add_edge(2*i+(f?0:1),2*j+(g?1:0));scc.add_edge(2*j+(g?0:1),2*i+(f?1:0));}boolsatisfiable(){autoid=scc.scc_ids().second;for(inti=0;i<_n;i++){if(id[2*i]==id[2*i+1])returnfalse;_answer[i]=id[2*i]<id[2*i+1];}returntrue;}std::vector<bool>answer(){return_answer;}private:int_n;std::vector<bool>_answer;internal::scc_graphscc;};}// namespace atcoder