#include <bits/stdc++.h>   using namespace std;   using namespace std;   void enumerateSubmasks(int m) {     for (int s = m;; s = (s - 1) & m) {       if (s == 0) {         break;       }     }   }   int mpow(int a, int b, int m) {     if (b == 0) return 1;     int x = mpow(a, b / 2, m);     x = (x * x) % m;     if (b % 2) {       x = (x * a) % m;     }     return x;   }   void update(int s, int e, int qs, int qe, vector<int> &seg, vector<int> &lazy,               int index, int value) {     if (lazy[index] != -1) {       seg[index] = max(seg[index], lazy[index]);       if (s != e) {         if (lazy[2 * index] == -1)           lazy[2 * index] = lazy[index];         else           lazy[2 * index] = max(lazy[2 * index], lazy[index]);         if (lazy[2 * index + 1] == -1)           lazy[2 * index + 1] = lazy[index];         else           lazy[2 * index + 1] = max(lazy[2 * index + 1], lazy[index]);       }       lazy[index] = -1;     }     if (qs > e || qe < s) return;     if (s >= qs && e <= qe) {       seg[index] = max(seg[index], value);       if (s != e) {         if (lazy[2 * index] == -1)           lazy[2 * index] = value;         else           lazy[2 * index] = max(lazy[2 * index], value);         if (lazy[2 * index + 1] == -1)           lazy[2 * index + 1] = value;         else           lazy[2 * index + 1] = max(lazy[2 * index + 1], value);       }       return;     }     int mid = (s + e) / 2;     update(s, mid, qs, qe, seg, lazy, 2 * index, value);     update(mid + 1, e, qs, qe, seg, lazy, 2 * index + 1, value);   }   int query(int s, int e, int qs, int qe, vector<int> &seg, vector<int> &lazy,             int index) {     if (lazy[index] != -1) {       seg[index] = max(seg[index], lazy[index]);       if (s != e) {         if (lazy[2 * index] == -1)           lazy[2 * index] = lazy[index];         else           lazy[2 * index] = max(lazy[2 * index], lazy[index]);         if (lazy[2 * index + 1] == -1)           lazy[2 * index + 1] = lazy[index];         else           lazy[2 * index + 1] = max(lazy[2 * index + 1], lazy[index]);       }       lazy[index] = -1;     }     if (qs > e || qe < s) return LLONG_MIN;     if (s >= qs && e <= qe) {       return seg[index];     }     int mid = (s + e) / 2;     int a = query(s, mid, qs, qe, seg, lazy, 2 * index);     int b = query(mid + 1, e, qs, qe, seg, lazy, 2 * index + 1);     return max(a, b);   }   void printBinaryString(int n) {     vector<int> temp;     while (n) {       if (n & 1)         temp.push_back(1);       else         temp.push_back(0);       n = n >> 1;     }     reverse(temp.begin(), temp.end());     for (auto node : temp) cout << node <<    ;     cout << endl;   }   void readVector(vector<int> &a) {     int n = a.size();     for (int i = 0; i < n; ++i) cin >> a[i];   }   vector<vector<int>> adj(100002);   vector<int> par(100002);   void dfs(int node, int parent) {     par[node] = parent;     for (auto child : adj[node]) {       if (child == parent) continue;       dfs(child, node);     }   }   int32_t main() {     ios_base::sync_with_stdio(false);     cin.tie(NULL);     int n;     cin >> n;     vector<pair<int, int>> graph;     for (int i = 0; i < n - 1; ++i) {       int u, v;       cin >> u >> v;       adj[u].push_back(v);       adj[v].push_back(u);       graph.push_back({u, v});     }     dfs(1, 1);     cout << n - 1 << endl;     for (int i = 2; i <= n; i++) {       cout << 2 <<     << i <<     << par[i] << endl;     }     int oneCousin = *adj[1].begin();     for (auto node : adj[1]) {       if (node == oneCousin) continue;       graph.push_back({oneCousin, node});     }     for (auto node : graph)       if (node.first != 1 && node.second != 1)         cout << node.first - 1 <<     << node.second - 1 << endl;   }