#include <bits/stdc++.h>
using namespace std;
int N;
vector<vector<int> > adj;
int ax, ay;
int vis[100000 + 5];
int ord[100000 + 5];
vector<pair<int, int> > vertices;
vector<pair<int, int> > edges;
struct I3 {
  int first;
  int second;
  int third;
  I3() { first = second = third = 0; }
  I3(int a_, int b_, int c_) : first(a_), second(b_), third(c_) {}
};
int main() {
  pair<int, int> ip;
  int v, prev, vertexCnt, prevTnode;
  int len, next;
  for (int i = 0; i <= 100000 + 5; i++) {
    vector<int> vec;
    adj.push_back(vec);
  }
  scanf("%d", &N);
  for (int i = 1; i < N; i++) {
    scanf("%d %d", &ax, &ay);
    adj[ax].push_back(ay);
    adj[ay].push_back(ax);
  }
  if (N == 2) {
    printf("1\n");
    printf("2 1 2\n");
  } else {
    queue<pair<int, int> > q;
    q.push(pair<int, int>(1, -1));
    vertexCnt = 0;
    vis[1] = 1;
    ord[1] = 1;
    while (!q.empty()) {
      ip = q.front();
      q.pop();
      v = ip.first;
      prev = ip.second;
      len = adj[v].size();
      for (int i = 0; i < len; i++) {
        next = adj[v][i];
        if (!vis[next]) {
          vis[next] = 1;
          vertices.push_back(pair<int, int>(v, next));
          vertexCnt++;
          ord[next] = vertexCnt;
          q.push(pair<int, int>(next, vertexCnt));
          if (ord[v] != vertexCnt) {
            edges.push_back(pair<int, int>(ord[v], vertexCnt));
          }
        }
      }
    }
    len = vertices.size();
    printf("%d\n", len);
    for (int i = 0; i < len; i++) {
      printf("2 %d %d\n", vertices[i].first, vertices[i].second);
    }
    len = edges.size();
    for (int i = 0; i < len; i++) {
      printf("%d %d\n", edges[i].first, edges[i].second);
    }
  }
  return 0;
}
