#include <bits/stdc++.h>
using namespace std;
const int dy[] = {-1, 0, 1, 0}, dx[] = {0, 1, 0, -1};
const double EPS = 1e-8;
const double PI = acos(-1.0);
int popcount(int n) { return __builtin_popcount(n); }
int popcount(long long n) { return __builtin_popcountll(n); }
template <class T>
int SIZE(T a) {
  return a.size();
}
template <class T>
string IntToString(T num) {
  string res;
  stringstream ss;
  ss << num;
  return ss.str();
}
template <class T>
T StringToInt(string str) {
  T res = 0;
  for (int i = 0; i < SIZE(str); i++) res = (res * 10 + str[i] - '0');
  return res;
}
template <class T>
T gcd(T a, T b) {
  if (b == 0) return a;
  return gcd(b, a % b);
}
template <class T>
T lcm(T a, T b) {
  return a / gcd(a, b) * b;
}
template <class T>
void PrintSeq(T &a, int sz) {
  for (int i = 0; i < sz; i++) {
    cout << a[i];
    if (sz == i + 1)
      cout << endl;
    else
      cout << ' ';
  }
}
bool EQ(double a, double b) { return abs(a - b) < EPS; }
void fastStream() {
  cin.tie(0);
  std::ios_base::sync_with_stdio(0);
}
vector<string> split(string str, char del) {
  vector<string> res;
  for (int i = 0, s = 0; i < SIZE(str); i++) {
    if (str[i] == del) {
      if (i - s != 0) res.push_back(str.substr(s, i - s));
      s = i + 1;
    } else if (i == SIZE(str) - 1) {
      res.push_back(str.substr(s));
    }
  }
  return res;
}
int froms[1000001];
int tos[1000001];
vector<pair<int, int> > G[1000001];
bool used[1000001];
void dfs(int pprv, int prv, int now) {
  used[now] = true;
  for (int i = 0; i < (int)G[now].size(); i++) {
    int to = G[now][i].first;
    int en = G[now][i].second;
    if (!used[to]) {
      dfs(prv, en, to);
    }
  }
  if (prv != -1 && pprv != -1) cout << pprv << " " << prv << endl;
}
int main() {
  fastStream();
  int N;
  cin >> N;
  for (int i = 0; i < N - 1; i++) {
    cin >> froms[i] >> tos[i];
    G[froms[i]].push_back(make_pair(tos[i], i + 1));
    G[tos[i]].push_back(make_pair(froms[i], i + 1));
  }
  cout << N - 1 << endl;
  for (int i = 0; i < N - 1; i++)
    cout << 2 << " " << froms[i] << " " << tos[i] << endl;
  for (int i = 0; i < N; i++) {
    if (G[i + 1].size() == 1) {
      dfs(-1, -1, i + 1);
      break;
    }
  }
  return 0;
}
