#include <bits/stdc++.h>
using namespace std;
struct Node {
  unordered_set<int> adj;
  int cnt;
};
int n;
vector<Node> graph;
struct Change {
  int fromX;
  int fromY;
  int toY;
};
vector<Change> changes;
int calcCnt(int v, int parent) {
  int cnt = 1;
  for (auto next : graph[v].adj)
    if (next != parent) cnt += calcCnt(next, v);
  graph[v].cnt = cnt;
  return graph[v].cnt;
}
pair<int, int> findCentroids() {
  calcCnt(0, 0);
  int v = 0;
  while (true) {
    int bestNext = *graph[v].adj.begin();
    for (auto next : graph[v].adj)
      if (graph[bestNext].cnt < graph[next].cnt) bestNext = next;
    if (graph[bestNext].cnt * 2 <= n) {
      if (graph[bestNext].cnt * 2 == n) return {v, bestNext};
      return {v, v};
    }
    graph[v].cnt = n - graph[bestNext].cnt;
    graph[bestNext].cnt = n;
    v = bestNext;
  }
}
pair<int, int> linearize(int v, int parent) {
  if (graph[v].adj.size() == 1) return {v, v};
  int cnt = graph[v].adj.size() - 1;
  int curParent = parent;
  int firstResSecond = v;
  for (auto next : graph[v].adj) {
    if (next != parent) {
      --cnt;
      auto res = linearize(next, v);
      if (cnt == 0) return {firstResSecond, res.second};
      changes.push_back({curParent, v, res.second});
      if (parent == curParent) firstResSecond = res.second;
      curParent = res.first;
    }
  }
}
int optimize(int v, int parent) {
  for (auto next : graph[v].adj) {
    if (next != parent) {
      const int res = optimize(next, v);
      changes.push_back({parent, v, res});
      return res;
    }
  }
  return v;
}
void applyChanges(int from) {
  for (int i = from; i < changes.size(); ++i) {
    const auto& change = changes[i];
    graph[change.fromX].adj.erase(change.fromY);
    graph[change.fromX].adj.insert(change.toY);
    graph[change.fromY].adj.erase(change.fromX);
    graph[change.toY].adj.insert(change.fromX);
  }
}
void solve(int v, int parent) {
  const int from = changes.size();
  for (auto subtree : graph[v].adj) {
    if (subtree != parent) linearize(subtree, v);
  }
  applyChanges(from);
  for (auto subtree : graph[v].adj) {
    if (subtree != parent) optimize(subtree, v);
  }
}
void solve() {
  changes.clear();
  graph.clear();
  scanf("%d", &n);
  if (n == 1) {
    puts("0");
    return;
  }
  graph.resize(n);
  for (int i = 1; i < n; ++i) {
    int a, b;
    scanf("%d %d", &a, &b);
    --a;
    --b;
    graph[a].adj.insert(b);
    graph[b].adj.insert(a);
  }
  const auto centroids = findCentroids();
  solve(centroids.first, centroids.second);
  if (centroids.first != centroids.second)
    solve(centroids.second, centroids.first);
  printf("%d\n", changes.size());
  for (const auto& r : changes)
    printf("%d %d %d\n", r.fromX + 1, r.fromY + 1, r.toY + 1);
}
int main() {
  solve();
  return 0;
}
