#include <queue>
#include <vector>
#include <set>
#include <iostream>
#include <fstream>
#include <utility>

using namespace std;

struct event
{
    int v, cnt;
    event(int v = 0, int cnt = 0) :
        v(v), cnt(cnt)
    {}

    bool operator<(const event& e) const
    {
        if (cnt != e.cnt)
            return cnt > e.cnt;
        return v > e.v;
    }
};

vector<set<int> > g;

vector<bool> used;

int dfs(int v, vector<int>& path)
{
    if (used[v])
        return 0;
    used[v] = true;
    path.push_back(v);
    int cnt = 1;
    for (set<int>::const_iterator it = g[v].begin(); it != g[v].end(); it++)
        cnt += dfs(*it, path);
    return cnt;
}

void dfs2(int v, vector<int>& path)
{
    if (used[v])
        return;
    path.push_back(v);
    if (g[v].size() == 3)
        return;
    used[v] = true;
    for (set<int>::const_iterator it = g[v].begin(); it != g[v].end(); it++)
        dfs2(*it, path);
}

int main()
{
    ifstream in("doggy.in");
    ofstream out("doggy.out");
    int n, m;
    in >> n >> m;
    g.resize(n);
    for (int i = 0; i < m; i++)
    {
        int a, b;
        in >> a >> b;
        g[a - 1].insert(b - 1);
        g[b - 1].insert(a - 1);
    }
    priority_queue<event> q;
    for (int i = 0; i < n; i++)
    {
        q.push(event(i, g[i].size()));
    }
    while (!q.empty())
    {
        event e = q.top();
        q.pop();
        if (e.cnt > 1)
            break;
        int prev = *(g[e.v].begin());
        g[prev].erase(e.v);
        g[e.v].erase(prev);
        q.push(event(prev, g[prev].size()));
    }

    bool has3 = false;
    int where3;
    for (int i = 0; i < n; i++)
    {
        has3 |= g[i].size() == 3;
        if (has3)
        {
            where3 = i;
            break;
        }
    }

    if (!has3)
    {
        int longest = -1;
        used = vector<bool>(n);
        vector<int> bestPath;
        for (int i = 0; i < n; i++)
            if (!used[i])
            {
                vector<int> path;
                int here = dfs(i, path);
                if (here > longest)
                {
                    longest = here;
                    bestPath = path;
                }
            }
        used = vector<bool>(n);
        out << bestPath.size() << "\n";
        for (size_t i = 0; i < bestPath.size(); i++)
            out << bestPath[i] + 1 << " ";
    }
    else
    {
        vector<vector<int> > pp;
        for (set<int>::const_iterator it = g[where3].begin(); it != g[where3].end(); it++)
        {
            vector<int> p;
            used = vector<bool>(n);
            used[where3] = true;
            dfs2(*it, p);
            pp.push_back(p);
        }
        if (pp[0].size() < pp[1].size())
            swap(pp[0], pp[1]);
        if (pp[1].size() < pp[2].size())
            swap(pp[1], pp[2]);
        if (pp[0].size() < pp[1].size())
            swap(pp[0], pp[1]);
        out << pp[0].size() + pp[1].size() << "\n";
        for (int i = 0; i < pp[0].size(); i++)
            out << (pp[0][i] + 1) << " ";
        for (int i = pp[1].size() - 2; i >= 0; i--)
            out << (pp[1][i] + 1) << " ";
        out << (where3 + 1) << "\n";
    }
}
