### BUGGY CODE ###

import collections
import random
def all_contains(s, a):
    return all([x in s for x in a])

n,m=map(int, input().split())
graph = [[] for i in range(n)]
cnt = [0 for i in range(n)]
for i in range(m):
    a,b = map(int, input().split())
    graph[a-1].append(b-1)
    graph[b-1].append(a-1)
    cnt[a-1] += 1
    cnt[b-1] += 1
for i in range(n):
    random.shuffle(graph[i])
start = random.randint(0, n-1)
for i in range(n):
    if cnt[i]<cnt[start]:
        start = i

def main():
    q = []
    q.append((start, []))
    while q:
        v, path = q.pop()
        path.append(v)
        if all_contains(path, graph[v]) and all_contains(path, graph[path[0]]):
            return path
        for nv in graph[v]:
            if nv not in path:
                q.append((nv, path[:]))

import itertools
def allow_path(path):
    for i in range(len(path)-1):
       if not path[i+1] in graph[path[i]]:
           return False
    return True

def sim():
    for pl in range(2, n+1):
        for path in itertools.permutations(range(n), r=pl):
            if all_contains(path, graph[path[0]]) and all_contains(path, graph[path[-1]]) and allow_path(path):
                return path

if __name__ == '__main__':
    res = main()
    # res = sim()
    # if res != res2:
    #     print(res)
    #     print(res2)
    print(len(res))
    print(' '.join([str(x+1) for x in res]))


### FIXED CODE ###

import heapq
def dijkstra_path(V, source, target):

    visited = [False] * V
    prev = [-1 for i in range(V)]


    dist = [float('inf')] * V
    dist[source] = 0

    h = [(0, source)]
    while h:
        c, v = heapq.heappop(h)
        if visited[v]:
            continue
        visited[v] = True
        for i in range(len(graph[v])):
            t = graph[v][i]
            nc = c + 1
            if dist[t] > nc:
                dist[t] = nc
                heapq.heappush(h, (nc, t))
                prev[t] = v
    path = [target]
    while path[-1] != source and path[-1] != -1:
        path.append(prev[path[-1]])
    return path[::-1]

def all_contains(s, a):
    return all([x in s for x in a])

n,m=map(int, input().split())
graph = [[] for i in range(n)]
cnt = [0 for i in range(n)]
for i in range(m):
    a,b = map(int, input().split())
    graph[a-1].append(b-1)
    graph[b-1].append(a-1)
    cnt[a-1] += 1
    cnt[b-1] += 1
start = 0
end = 1
for i in range(n):
    if cnt[i]<=cnt[start]:
        end = start
        start = i


def main():
    v = start
    path = [start]
    moved = [0 for i in range(n)]
    pre = [float('inf') for i in range(n)]
    while True:
        if path[-1] != v:
            path.append(v)
        # print(path[- min(len(path), 4):])
        if all_contains(path, graph[v]) and all_contains(path, graph[start]):
            return path

        while moved[v] < len(graph[v]):
            nv = graph[v][moved[v]]
            if nv not in path:
                pre[nv] = v
                moved[v] += 1
                v = nv
                break
            else:
                moved[v] += 1
        else:
            path.pop()
            moved[v] = 0
            v = pre[v]



def allow_path(path):
    for i in range(len(path)-1):
       if not path[i+1] in graph[path[i]]:
           print(i+1, path[i+1], 'not in ', graph[path[i]])
           return False
    return True

if __name__ == '__main__':
    if cnt[end] == 1:
        res = dijkstra_path(n, start, end)
    else:
        res = main()
    # print(allow_path(res))
    print(len(res))
    print(' '.join([str(x+1) for x in res]))