#include <bits/stdc++.h>
using namespace std;
template <class A, class B>
A cvt(B x) {
  stringstream s;
  s << x;
  A r;
  s >> r;
  return r;
}
typedef vector<int> VI;
typedef vector<pair<int, int> > VII;
typedef vector<string> VS;
vector<pair<int, int> > ed;
vector<int> edge[100010];
map<pair<int, int>, vector<int> > mp;
map<pair<int, int>, int> m;
int mark[100010];
void dfs(int u, int p, int q, int r) {
  if (p != -1 && q != -1 && r != -1) {
    mp[make_pair(min(q, r), max(q, r))].push_back(
        m[make_pair(min(p, q), max(p, q))]);
  }
  mark[u] = 1;
  for (int i = (int)0; i < (int)edge[u].size(); ++i) {
    if (mark[edge[u][i]] == 0) {
      dfs(edge[u][i], q, r, edge[u][i]);
    }
  }
  return;
}
int main() {
  int n, x, y, start;
  scanf("%d", &n);
  vector<int> tmp;
  for (int i = (int)0; i < (int)n - 1; ++i) {
    mark[i] = 0;
    cin >> x >> y;
    x--;
    y--;
    ed.push_back(make_pair(min(x, y), max(x, y)));
    edge[x].push_back(y);
    edge[y].push_back(x);
    mp[make_pair(min(x, y), max(x, y))] = tmp;
    m[make_pair(min(x, y), max(x, y))] = i;
  }
  mark[n - 1] = 0;
  for (int i = (int)0; i < (int)n; ++i) {
    if (edge[i].size() == 1) {
      start = i;
      break;
    }
  }
  dfs(start, -1, -1, start);
  cout << ed.size() << endl;
  for (int i = (int)0; i < (int)ed.size(); ++i) {
    cout << "2 " << ed[i].first + 1 << " " << ed[i].second + 1 << endl;
  }
  for (int i = (int)0; i < (int)ed.size(); ++i) {
    tmp = mp[ed[i]];
    for (int j = (int)0; j < (int)tmp.size(); ++j) {
      cout << i + 1 << " " << tmp[j] + 1 << endl;
    }
  }
  return 0;
}
