#include <bits/stdc++.h>
using namespace std;
typedef char* cstr;
const int oo = (~0u) >> 1;
const long long int ooll = (~0ull) >> 1;
const double inf = 1e+20;
const double eps = 1e-8;
const double pi = acos(-1.0);
const int MOD = 1000000007;
template <typename type>
inline bool cmax(type& a, const type& b) {
  return a < b ? a = b, true : false;
}
template <typename type>
inline bool cmin(type& a, const type& b) {
  return b < a ? a = b, true : false;
}
template <typename type>
inline type sqr(const type& first) {
  return first * first;
}
int dbcmp(const double& a, const double& b) {
  return (a > b + eps) - (a < b - eps);
}
int sgn(const double& first) { return dbcmp(first, 0); }
template <typename type>
inline type gcd(type a, type b) {
  if (b)
    while ((a %= b) && (b %= a))
      ;
  return a + b;
}
template <typename type>
inline type lcm(type a, type b) {
  return a * b / gcd(a, b);
}
template <typename type>
inline void bit_inc(vector<type>& st, int first, type inc) {
  while (first < ((int)(st).size())) st[first] += inc, first |= first + 1;
}
template <typename type>
inline type bit_sum(const vector<type>& st, int first) {
  type s = 0;
  while (first >= 0) s += st[first], first = (first & (first + 1)) - 1;
  return s;
}
template <typename type>
inline type bit_kth(const vector<type>& st, int k) {
  int first = 0, second = 0, z = 0;
  while ((1 << (++second)) < ((int)(st).size()))
    ;
  for (int i = (second - 1); i >= 0; --i) {
    if ((first += 1 << i) > ((int)(st).size()) || z + st[first - 1] > k)
      first -= 1 << i;
    else
      z += st[first - 1];
  }
  return first;
}
inline void make_set(vector<int>& set) {
  for (int i = (0); i < (((int)(set).size())); ++i) set[i] = i;
}
inline int find_set(vector<int>& set, int first) {
  int second = first, z;
  while (second != set[second]) second = set[second];
  while (first != set[first]) z = set[first], set[first] = second, first = z;
  return second;
}
inline bool union_set(vector<int>& set, int a, int b) {
  a = find_set(set, a), b = find_set(set, b);
  return a != b ? set[a] = b, true : false;
}
int n;
vector<int> adj[100000 + 2];
vector<pair<int, int> > tree;
map<pair<int, int>, int> treeid;
vector<pair<int, int> > treepre;
int main() {
  cin >> n;
  for (int i = (1); i < (n); ++i) {
    int a, b;
    cin >> a >> b;
    adj[a].push_back(b), adj[b].push_back(a);
  }
  queue<int> q;
  vector<int> d(n + 2, -1), pre(n + 2);
  q.push(1);
  d[1] = 0;
  pre[1] = 0;
  while (((int)(q).size())) {
    int u = q.front();
    q.pop();
    pair<int, int> tp = make_pair(pre[u], u);
    for (int i = (0); i < (((int)(adj[u]).size())); ++i) {
      int v = adj[u][i];
      if (d[v] == -1) {
        q.push(v);
        d[v] = d[u] + 1;
        pre[v] = u;
        tree.push_back(make_pair(u, v));
        treeid[tree.back()] = ((int)(tree).size());
        treepre.push_back(tp);
        tp = tree.back();
      }
    }
  }
  cout << ((int)(tree).size()) << endl;
  for (int i = (0); i < (((int)(tree).size())); ++i)
    cout << 2 << " " << tree[i].first << " " << tree[i].second << endl;
  for (int i = (1); i < (((int)(tree).size())); ++i)
    cout << i + 1 << " " << treeid[treepre[i]] << endl;
}
