#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef string str;

#define pb push_back
#define ppp pop_back
#define pii pair<int,int>
#define fi first
#define se second
#define stie std::tie
#define vec vector
#define	forn(i, l, r) for (int i=l; i<=r; i++)
#define forb(i, r, l) for (int i=r; i>=l; i--)
#define emp empty
#define beg begin
#define ins insert
#define cle clear
#define era erase
#define que queue
#define pque priority_queue
#define mset multiset
#define deq deque
#define sta stack
#define con const
#define rsz resize
#define ass assign
#define lowb lower_bound
#define uppb upper_bound

template<class T> void mini(T& a, T b) { a = min(a, b); }
template<class T> void maxi(T& a, T b) { a = max(a, b); }
template<class T1, class T2> ostream& operator<<(ostream &out, pair<T1, T2> a) { return out << a.first << " " << a.second; }
template<class T> ostream& operator<<(ostream& out, vector<T> a) { for (auto& i : a) out << i << " "; return out; }
template<class T> ostream& operator<<(ostream& out, set<T> a) { for (auto& i : a) out << i << " "; return out; }
template<class T> ostream& operator<<(ostream& out, multiset<T> a) { for (auto& i : a) out << i << " "; return out; }
template<class T1, class T2> ostream& operator<<(ostream& out, map<T1, T2> a) { for (auto& i : a) out << i << "\n"; return out; }
template<class T1, class T2> ostream& operator<<(ostream& out, unordered_map<T1, T2> a) { for (auto& i : a) out << i << "\n"; return out; }
template<class T> ostream& operator<<(ostream& out, queue<T> a) { while (!a.empty()) { out << a.front() << " "; a.pop(); } return out; }
template<class T> ostream& operator<<(ostream& out, deque<T> a) { while (!a.empty()) { out << a.front() << " "; a.pop_front(); } return out; }
template<class T> ostream& operator<<(ostream& out, priority_queue<T> a) { while (!a.empty()) { out << a.top() << "\n"; a.pop(); } return out; }
template<class T> void out(T a) { cout << a << endl; }
template<class T1, class T2> void out(T1 a, T2 b) { cout << a << " " << b << endl; }
template<class T1, class T2, class T3> void out(T1 a, T2 b, T3 c) { cout << a << " " << b << " " << c << endl; }
template<class T1, class T2, class T3, class T4> void out(T1 a, T2 b, T3 c, T4 d) { cout << a << " " << b << " " << c << " " << d << endl; }
template<class T> void out(vector<vector<T>> a) { for (vector<T> i : a) out(i); }
template<class T> void out_(T a[], int l, int r) { for (int i = l; i <= r; i++) cout << a[i] << " "; cout << endl; }
void out() { cout << "OK" << endl; }
template<class T> void sort(vector<T>& a) { sort(a.begin(), a.end()); }
template<class T> void uniq(vector<T>& a) { sort(a); a.erase(unique(a.begin(), a.end()), a.end()); }
template<class T> vector<T> set_int(vector<T> a, vector<T> b) { sort(a); sort(b); vector<T> res; set_intersection(a.begin(), a.end(), b.begin(), b.end(), back_inserter(res)); return res; }
clock_t start_time; void start_timer() { start_time = clock(); }
double get_time() { return (double)(clock() - start_time) / CLOCKS_PER_SEC; }
#if __SIZEOF_INT128__ >= 16
typedef __int128 LL;
istream& operator>>(istream& in, __int128& a) { int64_t b; cin >> b; a = b; return in; }
ostream& operator<<(ostream& out, const __int128 a) {
	unsigned __int128 b = a < 0 ? -a : a; char buf[128]; char* c = end(buf); do { --c; *c = "0123456789"[b % 10]; b /= 10; } while (b);
	if (a < 0) { --c; *c = '-'; } int len = end(buf) - c; out.rdbuf()->sputn(c, len); return out;
}
#endif

con int N = 3005;

set<int> g[N];
int p[N];
int d[N];
set<pii> used;
vec<int> path;
int comps;

void init(int n) {
	comps = n;
	forn(i, 1, n) {
		p[i] = i;
		d[i] = 0;
	}
	used.cle();
	path.cle();
}

int find(int v) {
	if (p[v] == v) return v;
	return p[v] = find(p[v]);
}

void unite(int u, int v) {
	u = find(u);
	v = find(v);
	if (u == v) return;
	if (d[u] < d[v]) swap(u, v);
	p[v] = u;
	if (d[u] == d[v]) d[u]++;
	comps--;
}

bool connected() {
	return comps == 1;
}

void rest(int i, set<int>& star) {
	for (int j : star) {
		g[i].ins(j);
		g[j].ins(i);
	}
}

void dfs(int v) {
	for (int u : g[v]) {
		if (used.count({min(u, v), max(u, v)})) continue;
		used.ins({min(u, v), max(u, v)});
		dfs(u);
		path.pb(u);
	}
}

void Solve() {
	int n, m;
	cin >> n >> m;
	forn(i, 1, m) {
		int u, v;
		cin >> u >> v;
		g[u].ins(v);
		g[v].ins(u);
	}
	forn(i, 1, n) {
		set<int> all;
		for (int j : g[i]) {
			if (g[j].size() & 1) all.ins(j);
		}
		vec<int> cand(all.begin(), all.end());
		cand.pb(0);
		for (int can : cand) {
			set<int> star = all;
			star.era(can);
			for (int j : star) {
				g[i].era(j);
				g[j].era(i);
			}
			init(n);
			set<int> odd;
			forn(v, 1, n) {
				for (int u : g[v]) {
					unite(v, u);
				}
				if ((g[v].size() & 1) && odd.size() <= 2) {
					odd.ins(v);
				}
			}
			if (odd.size() > 2) {
				rest(i, star);
				continue;
			}
			bool ok = 1;
			forn(v, 1, n) {
				if (!g[v].emp() && find(v) != find(i)) {
					ok = 0;
					break;
				}
			}
			if (!ok || (odd.size() == 2 && !odd.count(i))) {
				rest(i, star);
				continue;
			}
			dfs(i);
			path.pb(i);
			if (!star.emp()) path.pb(-1);
			for (int j : star) {
				path.pb(j);
				path.pb(i);
			}
			out(path.size());
			out(path);
			return;
		}
	}
	out(0);
}

int main() {
	ios_base::sync_with_stdio(0); cin.tie(0);
#ifdef LOCAL
	freopen("input.txt", "r", stdin);
#endif
	start_timer();
	Solve();
	return 0;
}
