#include <bits/stdc++.h>
using namespace std;
struct _nl {
} nl;
bool _ns = 0;
template <typename T>
void _p(const T& _) {
  if constexpr (is_same<T, _nl>()) {
    cout << "\n";
    _ns = 0;
  } else {
    if (_ns) cout << " ";
    cout << _;
    _ns = 1;
  }
}
template <typename... T>
void out(const T&... _) {
  (_p(_), ...);
}
int ii() {
  int _;
  cin >> _;
  return _;
}
template <bool dir = false>
vector<vector<int>> read_graph(int n, int m) {
  vector<vector<int>> edges(n, vector<int>());
  for (int i = 0; i < m; i++) {
    int a, b;
    cin >> a >> b;
    edges[a - 1].emplace_back(b - 1);
    if constexpr (!dir) edges[b - 1].emplace_back(a - 1);
  }
  return edges;
}
template <typename T>
T divup(T m, T n) {
  return (m + n - 1) / n;
}
template <typename T>
void vout(const vector<T>& x) {
  for (int i = 0; i < x.size(); i++) out(x[i]);
  out(nl);
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int n = ii(), m = ii(), k = ii();
  auto g = read_graph(n, m);
  int max_path = divup(2 * n, k);
  vector<int> visited(n);
  vector<int> cur_path;
  int clones_done = 0;
  auto xflush = [&]() {
    out(cur_path.size());
    vout(cur_path);
    cur_path.clear();
    clones_done++;
  };
  auto add_path_vx = [&](int vx) {
    if (cur_path.size() == max_path) xflush();
    cur_path.emplace_back(vx + 1);
  };
  function<void(int)> dfs = [&](int vx) {
    visited[vx] = true;
    add_path_vx(vx);
    for (auto vx1 : g[vx]) {
      if (!visited[vx1]) {
        dfs(vx1);
        add_path_vx(vx);
      }
    }
  };
  dfs(0);
  xflush();
  for (int i = 0; i < k - clones_done; i++) out(1, 1, nl);
  return 0;
}
