#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
const int N = 200000;
vector<pair<int, int> > g[N];
int depth[N], pa[N];
void dfs(int u, int par, int d) {
  pa[u] = par;
  depth[u] = d;
  for (pair<int, int>& i : g[u])
    if (i.first != par) dfs(i.first, u, d + 1);
}
void solve() {
  int n, u, v;
  cin >> n;
  for (int i = 1; i < n; i++) {
    cin >> u >> v;
    u--;
    v--;
    g[u].push_back({v, i});
    g[v].push_back({u, i});
  }
  dfs(0, -1, 0);
  for (int i = 1; i < n; i++)
    for (int j = 0; j < g[i].size(); j++)
      if (g[i][j].first == pa[i]) {
        g[i].erase(g[i].begin() + j);
        break;
      }
  int deg[n];
  deg[0] = g[0].size();
  for (int i = 1; i < n; i++) deg[i] = g[i].size() + 1;
  int max_deg = deg[0];
  for (int i = 1; i < n; i++) max_deg = max(max_deg, deg[i]);
  set<pair<int, int> > ver[max_deg + 1];
  ver[deg[0]].insert({depth[0], 0});
  for (int i = 1; i < n; i++) ver[deg[i]].insert({depth[i], i});
  cout << max_deg << "\n";
  for (int i = max_deg; i > 0; i--) {
    unordered_set<int> vis;
    vector<int> ans;
    for (auto j : ver[i]) {
      deg[j.second]--;
      if (vis.find(j.second) != vis.end()) continue;
      v = g[j.second].back().first;
      ans.push_back(g[j.second].back().second);
      if (deg[v] == i)
        vis.insert(v);
      else {
        ver[deg[v]].erase({depth[v], v});
        deg[v]--;
        ver[deg[v]].insert({depth[v], v});
      }
      g[j.second].pop_back();
    }
    cout << ans.size() << " ";
    for (int& j : ans) cout << j << " ";
    cout << "\n";
    if (i == 1) return;
    for (auto j : ver[i]) ver[i - 1].insert(j);
  }
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  solve();
}
