#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
#define CHECK(x) if(!(x)) return false;
#define SKIP(x) if((x)) continue;
#ifdef INFOARENA
#define ProblemName "party"
#endif
#define MCONCAT(A, B) A B
#ifdef ProblemName
#define InFile MCONCAT(ProblemName, ".in")
#define OuFile MCONCAT(ProblemName, ".out")
#else
#define InFile "fis.in"
#define OuFile "fis.out"
#endif
const int MAXN = 110;
template<class T> class jmenvect : public vector<T> {
public:
T& operator[](int n) {
if (n > 0)
return this->at(n);
else
return this->at(-n + (this->size() >> 1));
}
};
class graph {
private:
vector< list<int> > adiac;
vector< list<int> > neg_adiac;
public:
graph();
graph(int);
int size();
void newnod();
void newedge(int, int);
const list<int>& getList(int);
void rev_DFS(int, jmenvect<int>&, jmenvect<int>&);
bool SCC_DFS(int, int, jmenvect<int>&);
};
graph::graph() {
adiac.reserve(MAXN);
neg_adiac.reserve(MAXN);
}
graph::graph(int n) {
adiac.resize(n + 1);
neg_adiac.resize(n + 1);
}
int graph::size() {
return adiac.size();
}
void graph::newnod() {
neg_adiac.resize(size() + 1);
adiac.resize(size() + 1);
}
void graph::newedge(int n1, int n2) {
if (n1 > 0)
adiac[n1].push_back(n2);
else
neg_adiac[-n1].push_back(n2);
}
const list<int>& graph::getList(int n) {
if (n > 0)
return adiac[n];
else
return neg_adiac[-n];
}
void graph::rev_DFS(int nod, jmenvect<int>& visited, jmenvect<int> &finished) {
auto L = this->getList(-nod);
visited[nod] = 1;
for (auto i = L.begin(); i != L.end(); ++i)
if (!visited[-(*i)])
rev_DFS(-(*i), visited, finished);
finished.push_back(nod);
}
bool graph::SCC_DFS(int curComp, int nod, jmenvect<int>& visited) {
visited[nod] = curComp;
auto L = this->getList(nod);
for (auto i = L.begin(); i != L.end(); ++i) {
if (!visited[*i]) {
if (!SCC_DFS(curComp, *i, visited))
return false;
}
}
if (visited[-nod])
return false;
visited[-nod] = -curComp;
return true;
}
pair<jmenvect<int>, int> korasaju(graph* G) {
int N = G->size() - 1;
jmenvect<int> visisted;
visisted.resize((N << 1) + 1);
jmenvect<int> finished;
finished.reserve((N << 1) + 1);
for (int i = 1; i <= N; i++) {
if (!visisted[i])
G->rev_DFS(i, visisted, finished);
if (!visisted[-i])
G->rev_DFS(-i, visisted, finished);
}
visisted.assign((N << 1) + 1, 0);
int curComp = 0;
for (auto i = finished.rbegin(); i != finished.rend() - 1; ++i) {
curComp++;
if (!visisted[*i]) {
if (!G->SCC_DFS(curComp, *i, visisted)) {
jmenvect<int> dummyvect;
return{ dummyvect, 0 };
}
}
else
curComp--;
}
return{ visisted, curComp };
}
int main() {
assert(freopen(InFile, "r", stdin));
assert(freopen(OuFile, "w", stdout));
/*
0 : x v y
1 : !x -> !y <=> x v !y
2 : !y -> !x <=> y v !x
3 : !x v !y
*/
int N, M;
scanf("%d%d", &N, &M);
graph* G = new graph(N);
for (int i = 0; i < M; i++) {
int tip, a, b;
scanf("%d%d%d", &a, &b, &tip);
switch (tip) {
case 0:
break;
case 1:
b = -b;
break;
case 2:
a = -a;
break;
default:
a = -a;
b = -b;
break;
}
G->newedge(-a, b);
G->newedge(-b, a);
}
pair<jmenvect<int>, int> p = korasaju(G);
jmenvect<int>& SCC = p.first;
if (!SCC.size()) {
printf("-1\n");
return 0;
}
int nrComp = p.second;
jmenvect<char> cval;
cval.resize((nrComp << 1) + 1);
for (int i = 1; i <= nrComp; i++) {
cval[-i] = 0;
cval[i] = 1;
}
vector<int> sol;
for (int i = 1; i <= N; i++) {
if (cval[SCC[i]] == 1)
sol.push_back(i);
}
printf("%d\n", (int)sol.size());
for (const auto &it : sol)
printf("%d\n", it);
return 0;
}