#include <cstdlib>
#include <cstdio>
#include <vector>
#include <memory.h>

using namespace std;

const int MaxN = 20200;
const int MaxM = 200200;

struct edge {
	int v;
	bool asfalt;
	edge(int x, bool y) { v = x; asfalt = y; }; 
};

int dfs[MaxN], currSon[MaxN], city[MaxN];
vector<edge> adj[MaxN];
bool mark[MaxN];
int n, m, time, root, sol, a, b, c;

void DFS(int u) {
	int v;

	time++;
	dfs[u] = time;

	for (int i = 0; i < adj[u].size(); i++) {
		v = adj[u][i].v;
		
		// ako je u-v tree-edge i cvor v nije obidjen
		if (adj[u][i].asfalt && dfs[v] == 0) {
			currSon[u] = v;
			DFS(v);
		}
		// ako u-v nije tree-edge i cvor v je vec obidjen
		if (!adj[u][i].asfalt && dfs[v] != 0) {

			//tada je u-v back ili "cross" edge i markiramo krajeve
			mark[u] = true;
			mark[v] = true;

			//ako je u-v back edge, proverimo da li nam treba novi root
			if (currSon[v] != 0 && dfs[ currSon[v] ] > dfs[root])
				root = currSon[v];
		}
	}

	currSon[u] = 0;
}

void DFS2(int u) {
	int v;

	mark[u] = true;
	city[sol++] = u;

	for (int i = 0; i < adj[u].size(); i++) {
		v = adj[u][i].v;
		if (adj[u][i].asfalt && !mark[v])
			DFS2(v);
	}
}

int main() {

	FILE* inFile = fopen("asfalt.in", "r");
	FILE* outFile = fopen("asfalt.out", "w");

	fscanf(inFile, "%d%d", &n, &m);
	for (int i = 0; i < m; i++) {
		fscanf(inFile, "%d%d%d", &a, &b, &c);
		adj[a].push_back(edge(b, c == 1));
		adj[b].push_back(edge(a, c == 1));
	}

	memset(dfs, 0, sizeof(dfs));
	memset(currSon, 0, sizeof(currSon));
	memset(mark, false, sizeof(mark));
	root = 1;  time = 0;  sol = 0;

	DFS(1);
	DFS2(root);

	fprintf(outFile, "%d\n", sol);
	for (int i = 0; i < sol - 1; i++)
		fprintf(outFile, "%d ", city[i]);
	fprintf(outFile, "%d\n", city[sol - 1]);

	return 0;
}