#include <bits/stdc++.h>
using namespace std;
vector<int> L[100005];
bool vis[100005];
vector<pair<int, int> > V;
void DFS(int node, int pd) {
  if (vis[node]) return;
  vis[node] = 1;
  V.push_back(make_pair(node, pd));
  for (int i = 0; i < L[node].size(); i++) {
    int to = L[node][i];
    DFS(to, node);
  }
}
map<pair<int, int>, int> M;
int pd[100005];
int Find(int x) {
  if (x == pd[x]) return x;
  return pd[x] = Find(pd[x]);
}
void Union(int x, int y) {
  x = Find(x);
  y = Find(y);
  pd[x] = y;
}
int main() {
  int n;
  while (cin >> n) {
    int x, y;
    for (int i = 0; i < n - 1; i++) {
      cin >> x >> y;
      L[x].push_back(y);
      L[y].push_back(x);
    }
    memset(vis, 0, sizeof vis);
    DFS(1, 1);
    int tam = V.size() - 1;
    cout << tam << endl;
    for (int i = 1; i < V.size(); i++) {
      cout << 2 << " " << V[i].first << " " << V[i].second << endl;
      M[V[i]] = i;
      swap(V[i].first, V[i].second);
      M[V[i]] = i;
    }
    for (int i = 0; i <= n; i++) pd[i] = i;
    vector<pair<int, int> > edge;
    memset(vis, 0, sizeof vis);
    for (int i = 1; i < V.size(); i++) {
      if (vis[i]) continue;
      vis[i] = 1;
      int u = V[i].first;
      int v = V[i].second;
      for (int j = 0; j < L[u].size(); j++) {
        int to = L[u][j];
        int label = M[make_pair(u, to)];
        if (Find(i) != Find(label)) {
          Union(i, label);
          edge.push_back(make_pair(i, label));
          vis[label] = 1;
        }
      }
      for (int j = 0; j < L[v].size(); j++) {
        int to = L[v][j];
        int label = M[make_pair(v, to)];
        if (Find(i) != Find(label)) {
          Union(i, label);
          edge.push_back(make_pair(i, label));
          vis[label] = 1;
        }
      }
    }
    for (int i = 0; i < edge.size(); i++)
      cout << edge[i].first << " " << edge[i].second << endl;
  }
}
