#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <stack>
#include <vector>
#include <set>
using namespace std;
class Edge
{
private:
unsigned first;
unsigned second;
double weight;
public:
Edge(unsigned = 0, unsigned = 0, double = 0);
unsigned from() const;
unsigned to() const;
double length() const;
bool operator< (const Edge&) const;
bool operator> (const Edge&) const;
bool operator<= (const Edge&) const;
bool operator>= (const Edge&) const;
bool operator== (const Edge&) const;
bool operator!= (const Edge&) const;
};
class DWGraph
{
private:
vector<multiset<Edge> > vertices;
public:
DWGraph(unsigned = 1024);
unsigned size() const;
void addVertex();
void edge(unsigned, unsigned, double);
const multiset<Edge>& adj(unsigned) const;
unsigned degree(unsigned) const;
};
Edge::Edge(unsigned from, unsigned to, double length)
{
this->first = from;
this->second = to;
this->weight = length;
}
unsigned Edge::from() const
{
return this->first;
}
unsigned Edge::to() const
{
return this->second;
}
double Edge::length() const
{
return this->weight;
}
bool Edge::operator< (const Edge& other) const
{
return this->weight < other.weight;
}
bool Edge::operator> (const Edge& other) const
{
return this->weight > other.weight;
}
bool Edge::operator<= (const Edge& other) const
{
return this->weight <= other.weight;
}
bool Edge::operator>= (const Edge& other) const
{
return this->weight >= other.weight;
}
bool Edge::operator== (const Edge& other) const
{
return this->weight == other.weight;
}
bool Edge::operator!= (const Edge& other) const
{
return this->weight != other.weight;
}
DWGraph::DWGraph(unsigned vertices)
{
this->vertices.resize(vertices);
}
unsigned DWGraph::size() const
{
return this->vertices.size();
}
void DWGraph::addVertex()
{
this->vertices.push_back(multiset<Edge>());
}
void DWGraph::edge(unsigned from, unsigned to, double weight)
{
this->vertices.at(from).insert(Edge(from, to, weight));
}
const multiset<Edge>& DWGraph::adj(unsigned vertex) const
{
return this->vertices.at(vertex);
}
unsigned DWGraph::degree(unsigned vertex) const
{
return this->vertices.at(vertex).size();
}
template <class keyType>
class IndexedMinPQ
{
private:
const unsigned Nmax;
unsigned n;
vector<unsigned> pq;
vector<unsigned> qp;
vector<keyType> keys;
const unsigned no_key = 0;
void swap(unsigned i, unsigned j)
{
std::swap(pq[i], pq[j]);
qp[pq[i]] = i;
qp[pq[j]] = j;
}
bool greater(unsigned i, unsigned j)
{
return keys[pq[i]] > keys[pq[j]];
}
void sink(unsigned i)
{
unsigned j = i << 1;
while (j <= n)
{
if (j + 1 <= n)
{
if (greater(j, j + 1))
{
++j;
}
}
if (greater(i, j))
{
swap(i, j);
i = j;
j <<= 1;
}
else break;
}
}
void swim(unsigned i)
{
unsigned j = i >> 1;
while (j > 0)
{
if (greater(j, i))
{
swap(i, j);
i = j;
j >>= 1;
}
else break;
}
}
public:
IndexedMinPQ(unsigned max) : Nmax(max)
{
n = 0;
pq.resize(Nmax + 1, no_key);
qp.resize(Nmax + 1, no_key);
keys.resize(Nmax + 1);
}
bool push(unsigned index, const keyType& key)
{
if (!contains(index))
{
n++;
pq[n] = index;
qp[index] = n;
keys[index] = key;
swim(n);
return true;
}
else return false;
}
bool contains(unsigned index) const
{
return qp[index] != no_key;
}
bool changeKey(unsigned index, const keyType& key)
{
if (contains(index))
{
keys[index] = key;
swim(qp[index]);
sink(qp[index]);
return true;
}
else return false;
}
unsigned topIndex() const
{
return pq[1];
}
const keyType& topKey() const
{
return keys[pq[1]];
}
bool pop()
{
if (!empty())
{
unsigned min = pq[1];
swap(1, n);
pq[n] = no_key;
qp[min] = no_key;
n--;
sink(1);
return true;
}
else return false;
}
unsigned size() const
{
return n;
}
bool empty() const
{
return n == 0;
}
};
//class Dijkstra
//{
//private:
// vector<int> from;
// vector<double> dist;
// vector<bool> marked;
//
// const double infinit = 202390219784947236478923467894687.01;
//
//public:
// Dijkstra(const DWGraph& g, int begin)
// {
// from.resize(g.size(), -1);
// dist.resize(g.size(), infinit);
// marked.resize(g.size(), false);
// dist[begin] = 0;
//
// IndexedMinPQ<double> pq(g.size());
// pq.push(begin, 0);
// while (!pq.empty())
// {
// int vertex = pq.topIndex();
// pq.pop();
// marked[vertex] = true;
// for (const Edge& e: g.adj(vertex))
// {
// int v = e.to();
// if (!marked[v])
// {
// double alt = dist[vertex] + e.length();
// if (alt < dist[v])
// {
// dist[v] = alt;
// from[v] = vertex;
// if (!pq.changeKey(v, alt))
// {
// pq.push(v, alt);
// }
// }
// }
// }
// }
// }
//
// double shortestPath(int begin, int end) // atat de gresit...
// {
// double ans = 0;
// while (end != -1 && from[end] != begin)
// {
// ans += dist[end];
// end = from[end];
// }
// ans += from[begin];
//
// return ans;
// }
//};
class DFS
{
private:
int Mdepth;
vector<bool> marked;
public:
DFS(const DWGraph& g, int index)
{
marked.resize(g.size(), false);
stack<int> st;
st.push(index);
marked[index] = true;
vector<int> depth(g.size(), 0);
while (!st.empty())
{
int v = st.top();
st.pop();
for (const Edge& e: g.adj(v))
{
if (!marked[e.to()])
{
st.push(e.to());
marked[e.to()] = true;
depth[e.to()] = depth[v] + 1;
}
}
}
Mdepth = *max_element(depth.begin(), depth.end());
}
int getDepth()
{
return Mdepth;
}
};
class AltDFS
{
private:
int Mdepth;
vector<bool> marked;
public:
AltDFS(const DWGraph& g, const vector<bool>& spitale, int index)
{
marked.resize(g.size(), false);
stack<int> st;
st.push(index);
marked[index] = true;
vector<int> depth(g.size(), 0);
while (!st.empty())
{
int v = st.top();
st.pop();
for (const Edge& e: g.adj(v))
{
if (spitale[e.to()])
continue;
if (!marked[e.to()])
{
st.push(e.to());
marked[e.to()] = true;
depth[e.to()] = depth[v] + 1;
}
}
}
Mdepth = *max_element(depth.begin(), depth.end());
}
int getDepth()
{
return Mdepth;
}
};
int main()
{
ifstream in("salvare.in");
ofstream out("salvare.out");
// int n, m, k;
//
// in >> n >> m >> k;
//
// DWGraph g(n);
// int a, b, c;
// for (int i = 0; i < m; i++)
// {
// in >> a >> b >> c;
// g.edge(a - 1, b - 1, c);
// g.edge(b - 1, a - 1, c);
// }
//
// Dijkstra d(g, 0);
//
// for (int i = 0; i < k; i++)
// {
// in >> a >> b;
// out << d.shortestPath(a - 1, b - 1) << '\n';
// }
int n, k;
in >> n >> k;
DWGraph g(n + 1);
int a, b;
for (int i = 0; i < n; i++)
{
in >> a >> b;
g.edge(a, b, 1);
g.edge(b, a, 1);
}
IndexedMinPQ<int> pq(n + 1);
for (int i = 1; i <= n; i++)
{
pq.push(i, DFS(g, i).getDepth());
}
vector<bool> spitale(n + 1);
for (int i = 0; i < k; i++)
{
spitale[pq.topIndex()] = true;
pq.pop();
}
int MaxD = 0;
for (int i = 1; i <= n; i++)
{
if (spitale[i])
{
int ans = AltDFS(g, spitale, i).getDepth();
if (ans > MaxD)
MaxD = ans;
}
}
out << MaxD << endl;
for (int i = 1; i <= n; i++)
{
if (spitale[i])
{
out << i << ' ';
}
}
in.close();
out.close();
}