#include <fstream>
#include <iostream>
#include <vector>
#include <stack>
#include <bitset>
#include <algorithm>
#define MAXN 100001
using namespace std;
struct Node
{
Node() : index(-1), lowlink(0), bIsOnStack(false)
{}
int index, lowlink;
bool bIsOnStack;
};
typedef unsigned int uint32;
typedef vector<vector<int> > Graph;
typedef vector<vector<int> > Scc;
uint32 formula[2*MAXN+1];
uint32 whatComponent[2*MAXN+1];
bitset<2*MAXN+1> nodeHasIncomingEdges;
bitset<2*MAXN+1> compHasIncomingEdges;
namespace TopologicalSort
{
uint32 *orderedComponents;
bitset<2*MAXN> visitedComponents;
uint32 uCurrentNode;
void SortComponentsTopologically(const Graph& graph, const Scc& sccs, const uint32 node)
{
for (uint32 i=0; i<sccs[node].size(); ++i)
{
for (uint32 j=0; j<graph[sccs[node][i]].size(); ++j)
{
if (false == visitedComponents[whatComponent[graph[sccs[node][i]][j]]])
{
visitedComponents[whatComponent[graph[sccs[node][i]][j]]] = true;
SortComponentsTopologically(graph, sccs, whatComponent[graph[sccs[node][i]][j]]);
}
}
}
orderedComponents[uCurrentNode++] = node;
}
inline void SortComponentsTopoligically(const Graph& graph, const Scc& sccs, uint32 uNumComp)
{
uCurrentNode = 0;
orderedComponents = new uint32[uNumComp+1];
for (uint32 i=0; i<uNumComp; ++i)
{
if (false == visitedComponents[i] && false == compHasIncomingEdges[i])
{
//cout << "Comp = " << i << endl;
visitedComponents[i] = true;
SortComponentsTopologically(graph, sccs, i);
}
}
}
}
inline uint32 non(const uint32 x, const uint32 n)
{
return (x>=n) ? (x - ((x-n)*2 + 1)) : (x + ((n-x)*2 - 1));
}
inline int original(const uint32 x, const uint32 n)
{
return (x>=n) ? (x-n+1) : (x-n);
}
void StronglyConnectedComponent
(
const Graph& graph,
Node *nodes,
stack<int>& S,
const int node,
int& index,
Scc& sccs,
int& numComp
)
{
nodes[node].index = index;
nodes[node].lowlink = index;
index++;
S.push(node);
nodes[node].bIsOnStack = true;
for (int i=0; i<graph[node].size(); ++i)
{
if (-1 == nodes[graph[node][i]].index)
{
StronglyConnectedComponent(graph, nodes, S, graph[node][i], index, sccs, numComp);
nodes[node].lowlink = min(nodes[node].lowlink, nodes[graph[node][i]].lowlink);
}
else if (nodes[graph[node][i]].bIsOnStack)
{
nodes[node].lowlink = min(nodes[node].lowlink, nodes[graph[node][i]].index);
}
}
if (nodes[node].lowlink == nodes[node].index)
{
int curNode;
do
{
curNode = S.top();
sccs[numComp].push_back(curNode);
nodes[curNode].bIsOnStack = false;
whatComponent[curNode] = numComp;
if (nodeHasIncomingEdges[curNode] == true)
compHasIncomingEdges[numComp] = true;
S.pop();
} while(!S.empty() && curNode!=node);
numComp++;
}
}
int StronglyConnectedComponents(const Graph& graph, Scc& sccs)
{
int index = 0, numComp = 0;
Node *nodes;
stack<int> S;
nodes = new Node[graph.size()+1];
sccs.resize(graph.size());
for (int i=0; i<graph.size(); ++i)
{
if (-1 == nodes[i].index)
{
StronglyConnectedComponent(graph, nodes, S, i, index, sccs, numComp);
}
}
if (!S.empty())
{
int curNode;
do
{
curNode = S.top();
sccs[numComp].push_back(curNode);
whatComponent[curNode] = numComp;
if (nodeHasIncomingEdges[curNode] == true)
compHasIncomingEdges[numComp] = true;
S.pop();
numComp++;
} while(!S.empty());
}
delete[] nodes;
return numComp;
}
int main()
{
uint32 numComp, variables, statements;
Graph graph;
Scc sccs;
fstream fin("2sat.in", fstream::in);
fstream fout("2sat.out", fstream::out);
fin >> variables >> statements;
//cout << variables << " " << statements << endl;
//n = variables;
//m = statements;
graph.resize(2*variables);
for (uint32 i=0; i<statements; ++i)
{
int x, y;
fin >> x >> y;
if (x<0)
{
x += variables;
}
else
{
x += (variables-1);
}
if (y<0)
{
y += variables;
}
else
{
y += (variables-1);
}
graph[non(x, variables)].push_back(y);
graph[non(y, variables)].push_back(x);
nodeHasIncomingEdges[x] = true;
nodeHasIncomingEdges[y] = true;
}
/*for (int i=0; i<n; ++i)
{
cout << i+1 << ": ";
for (int j=0; j<graph[i].size(); ++j)
{
cout << graph[i][j]+1 << " ";
}
cout << endl;
}
cout << endl;*/
numComp = StronglyConnectedComponents(graph, sccs);
for (uint32 i=0; i<variables; ++i)
{
if (whatComponent[i] == whatComponent[non(i, variables)])
{
fout << -1;
return 0;
}
}
/*TopologicalSort::SortComponentsTopoligically(graph, sccs, numComp);
//fout << numComp << "\n";
for (int i=numComp-1; i>=0; --i)
{
for (uint32 j=0; j<sccs[TopologicalSort::orderedComponents[i]].size(); ++j)
{
if (0 == formula[sccs[TopologicalSort::orderedComponents[i]][j]])
{
formula[sccs[TopologicalSort::orderedComponents[i]][j]] = 1;
formula[non(sccs[TopologicalSort::orderedComponents[i]][j], variables)] = 2;
}
//fout << original(sccs[TopologicalSort::orderedComponents[i]][j], variables) << " ";
}
//fout << "\n";
}
for (uint32 i=variables; i<2*variables; ++i)
{
fout << formula[i]-1 << " ";
}
fout << "\n";*/
fin.close();
fout.close();
return 0;
}