#pragma GCC optimize ("Ofast")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>
using namespace std;

// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
// template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef string str;

typedef pair<int,int> pi;
typedef pair<ll,ll> pll;
typedef pair<double, double> pd;
typedef pair<ld,ld> pld;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pf push_front
#define ins insert
#define lb lower_bound
#define ub upper_bound
#define rsz resize
#define all(x) begin(x), end(x)
#define rall(x) (x).rbegin(), (x).rend()
#define sz(x) (int) (x).size()
#define sor(x) sort(all(x))

#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define ROF(i,a,b) for (int i = (b)-1; i >= (a); --i)
#define R0F(i,a) ROF(i,0,a)
#define trav(a,x) for (auto& a: x)

template <typename T> inline T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }
template <typename T> inline T lcm(T a, T b) { return a / gcd(a, b) * b; }
template <class T> void ckmin(T& a, T b) { a = min(a, b); }
template <class T> void ckmax(T& a, T b) { a = max(a, b); }

// (Integer/Long).bitCount(x)
int pct(int x) { return __builtin_popcount(x); }
int pctll(ll x) { return __builtin_popcountll(x); }

void setIn(string s) { freopen(s.c_str(),"r",stdin); }
void setOut(string s) { freopen(s.c_str(),"w",stdout); }
void unsyncIO() { ios_base::sync_with_stdio(0); cin.tie(0); }
void setIO(string s = "") {
	unsyncIO();
	if (sz(s)) { setIn(s+".in"), setOut(s+".out"); }
}

ll pow(ll b, ll e, ll m = 0LL, ll ans = 1LL) { while (e) { if (e & 1LL) { ans *= b; if (m) ans %= m; } b *= b, e >>= 1LL; if (m) b %= m; } return ans; }
template <typename T> vector<T> readVector(int n) { vector<T> res(n); for (int i = 0 ; i < n ; i++) cin >> res[i]; return res; }

const int MOD = 1e9+7; // 998244353;
const int mxN = 2e5+5;
const int INF = 2e9;
const ll INFLL = 1e18;
const ld PI = acos((ld)-1);
const ld EPS = 1e-8;
const int dx4[4] = {1, 0, -1, 0}, dy4[4] = {0, 1, 0, -1};
const int dx8[8] = {-1, -1, 0, 1, 1, 1, 0, -1}, dy8[8] = {0, 1, 1, 1, 0, -1, -1, -1};
const char nl = '\n';

int n;
vector<int> adj[mxN];
bool deleted[mxN];
int deg[mxN];
unordered_set<int> leaves;
vector<pair<pi, int> > ans;

void dfs(vector<int>& dist, int u, int p, int d, bool flag) {
	dist[u] = d;
	trav(v, adj[u]) {
		if (v != p) {
			dfs(dist, v, u, d+1, flag);
			if (flag) {
				++deg[u], ++deg[v];
			}
		}
	}
}

int furthest(int from, bool flag) {
	vector<int> dist(n, INF);
	dfs(dist, from, -1, 0, flag);
	int ans = 0;
	F0R(i, n) {
		if (dist[i] > dist[ans]) {
			ans = i;
		}
	}
	return ans;
}

vector<int> calcDists(int from) {
	vector<int> dist(n, INF);
	dfs(dist, from, -1, 0, false);
	return dist;
}

void solve(int tcn) {
	cin >> n;
	F0R(i, n-1) {
		int u, v;
		cin >> u >> v;
		--u, --v;
		adj[u].pb(v);
		adj[v].pb(u);
	}
	int x = furthest(0, true);
	int y = furthest(x, false);
	// cout << x << " " << y << nl;
	// Diameter = path from x to y
	F0R(i, n) {
		if (sz(adj[i]) == 1 && i != x && i != y) {
			leaves.ins(i);
		}
	}
	ll cost = 0LL;
	vector<int> xx = calcDists(x), yy = calcDists(y);
	while (!leaves.empty()) {
		auto f = leaves.begin();
		int u = *f;
		cout << "Currently deleting " << u << nl;
		if (xx[u] > yy[u]) {
			ans.pb(mp(mp(u, x), xx[u]));
			cost += xx[u];
		} else {
			ans.pb(mp(mp(u, y), yy[u]));
			cost += yy[u];
		}
		leaves.erase(f);
		deleted[u] = true;
		trav(v, adj[u]) {
			--deg[v];
			if (deg[v] == 1 && !deleted[v] && v != x && v != y) {
				leaves.ins(v);
			}
		}
	}
	leaves.clear();
	leaves.ins(y);
	while (!leaves.empty()) {
		auto f = leaves.begin();
		int u = *f;
		ans.pb(mp(mp(u, x), xx[u]));
		// cout << "Currently deleting " << u << nl;
		cost += xx[u];
		leaves.erase(f);
		deleted[u] = true;
		trav(v, adj[u]) {
			--deg[v];
			// cout << "Considering " << v << " Degree of " << deg[v] << nl;
			if (deg[v] == 1 && !deleted[v] && v != x) {
				leaves.ins(v);
			}
		}
	}
	cout << cost << nl;
	F0R(i, n-1) {
		cout << ans[i].fi.fi+1 << " " << ans[i].fi.se+1 << " " << ans[i].fi.fi+1 << nl;
	}
}

int main() {
    setIO("");

    int t = 1; //cin >> t;
	for (int i = 1; i <= t; ++i) {
		//cout << "Case #" << i << ": ";
		solve(i);
	}
	return 0;
}


#pragma GCC optimize ("Ofast")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>
using namespace std;

// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
// template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef string str;

typedef pair<int,int> pi;
typedef pair<ll,ll> pll;
typedef pair<double, double> pd;
typedef pair<ld,ld> pld;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pf push_front
#define ins insert
#define lb lower_bound
#define ub upper_bound
#define rsz resize
#define all(x) begin(x), end(x)
#define rall(x) (x).rbegin(), (x).rend()
#define sz(x) (int) (x).size()
#define sor(x) sort(all(x))

#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define ROF(i,a,b) for (int i = (b)-1; i >= (a); --i)
#define R0F(i,a) ROF(i,0,a)
#define trav(a,x) for (auto& a: x)

template <typename T> inline T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }
template <typename T> inline T lcm(T a, T b) { return a / gcd(a, b) * b; }
template <class T> void ckmin(T& a, T b) { a = min(a, b); }
template <class T> void ckmax(T& a, T b) { a = max(a, b); }

// (Integer/Long).bitCount(x)
int pct(int x) { return __builtin_popcount(x); }
int pctll(ll x) { return __builtin_popcountll(x); }

void setIn(string s) { freopen(s.c_str(),"r",stdin); }
void setOut(string s) { freopen(s.c_str(),"w",stdout); }
void unsyncIO() { ios_base::sync_with_stdio(0); cin.tie(0); }
void setIO(string s = "") {
	unsyncIO();
	if (sz(s)) { setIn(s+".in"), setOut(s+".out"); }
}

ll pow(ll b, ll e, ll m = 0LL, ll ans = 1LL) { while (e) { if (e & 1LL) { ans *= b; if (m) ans %= m; } b *= b, e >>= 1LL; if (m) b %= m; } return ans; }
template <typename T> vector<T> readVector(int n) { vector<T> res(n); for (int i = 0 ; i < n ; i++) cin >> res[i]; return res; }

const int MOD = 1e9+7; // 998244353;
const int mxN = 2e5+5;
const int INF = 2e9;
const ll INFLL = 1e18;
const ld PI = acos((ld)-1);
const ld EPS = 1e-8;
const int dx4[4] = {1, 0, -1, 0}, dy4[4] = {0, 1, 0, -1};
const int dx8[8] = {-1, -1, 0, 1, 1, 1, 0, -1}, dy8[8] = {0, 1, 1, 1, 0, -1, -1, -1};
const char nl = '\n';

int n;
vector<int> adj[mxN];
bool deleted[mxN];
int deg[mxN];
unordered_set<int> leaves;
vector<pair<pi, int> > ans;

void dfs(vector<int>& dist, int u, int p, int d, bool flag) {
	dist[u] = d;
	trav(v, adj[u]) {
		if (v != p) {
			dfs(dist, v, u, d+1, flag);
			if (flag) {
				++deg[u], ++deg[v];
			}
		}
	}
}

int furthest(int from, bool flag) {
	vector<int> dist(n, INF);
	dfs(dist, from, -1, 0, flag);
	int ans = 0;
	F0R(i, n) {
		if (dist[i] > dist[ans]) {
			ans = i;
		}
	}
	return ans;
}

vector<int> calcDists(int from) {
	vector<int> dist(n, INF);
	dfs(dist, from, -1, 0, false);
	return dist;
}

void solve(int tcn) {
	cin >> n;
	F0R(i, n-1) {
		int u, v;
		cin >> u >> v;
		--u, --v;
		adj[u].pb(v);
		adj[v].pb(u);
	}
	int x = furthest(0, true);
	int y = furthest(x, false);
	// cout << x << " " << y << nl;
	// Diameter = path from x to y
	F0R(i, n) {
		if (sz(adj[i]) == 1 && i != x && i != y) {
			leaves.ins(i);
		}
	}
	ll cost = 0LL;
	vector<int> xx = calcDists(x), yy = calcDists(y);
	while (!leaves.empty()) {
		auto f = leaves.begin();
		int u = *f;
		// cout << "Currently deleting " << u << nl;
		if (xx[u] > yy[u]) {
			ans.pb(mp(mp(u, x), xx[u]));
			cost += xx[u];
		} else {
			ans.pb(mp(mp(u, y), yy[u]));
			cost += yy[u];
		}
		leaves.erase(f);
		deleted[u] = true;
		trav(v, adj[u]) {
			--deg[v];
			if (deg[v] == 1 && !deleted[v] && v != x && v != y) {
				leaves.ins(v);
			}
		}
	}
	leaves.clear();
	leaves.ins(y);
	while (!leaves.empty()) {
		auto f = leaves.begin();
		int u = *f;
		ans.pb(mp(mp(u, x), xx[u]));
		// cout << "Currently deleting " << u << nl;
		cost += xx[u];
		leaves.erase(f);
		deleted[u] = true;
		trav(v, adj[u]) {
			--deg[v];
			// cout << "Considering " << v << " Degree of " << deg[v] << nl;
			if (deg[v] == 1 && !deleted[v] && v != x) {
				leaves.ins(v);
			}
		}
	}
	cout << cost << nl;
	F0R(i, n-1) {
		cout << ans[i].fi.fi+1 << " " << ans[i].fi.se+1 << " " << ans[i].fi.fi+1 << nl;
	}
}

int main() {
    setIO("");

    int t = 1; //cin >> t;
	for (int i = 1; i <= t; ++i) {
		//cout << "Case #" << i << ": ";
		solve(i);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
const int inf=0x3f3f3f3f;
int vis[maxn],dep2[maxn],dep[maxn],n,cnt,rt,u,v;
long long ans;
int buf[maxn][4];
vector<int> g[maxn];
vector<int> e;
void dfs(int x,int fa)
{
	if((dep[x]=dep[fa]+1)>dep[rt])
		rt=x;
	for(int y:g[x])
		if(y!=fa)
			dfs(y,x);
}
int dfs2(int x,int fa)
{
	dep2[x]=dep2[fa]+1;
	for(int y:g[x])
	{
		if(y!=fa)
		{
			if(dfs2(y,x))
			{
				vis[x]=1;
				e.push_back(x);
			}
		}
	}
	return vis[x];
}
void dfs3(int x,int fa)
{
	for(int y:g[x])
		if(y!=fa)
			dfs3(y,x);
	if(!vis[x])
	{
		++cnt;
		buf[cnt][2]=buf[cnt][3]=x;
		if(dep[x]>dep2[x])
		{
			ans+=dep[x];
			buf[cnt][1]=u;
		}
		else
		{
			ans+=dep2[x];
			buf[cnt][1]=rt;
		}
	}
}
int main(){
	cin>>n;
	for(int i=2;i<=n;i++)
	{
		cin>>u>>v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	dfs(rt=1,0);
	dep[0]=-1;
	dfs(u=rt,0);
	vis[u]=1;
	dep2[0]=-1;
	dfs2(rt,0);
	dfs3(rt,0);
	while(e.size())
	{
		++cnt;
		buf[cnt][1]=u;
		buf[cnt][2]=buf[cnt][3]=e.back();
		ans+=e.size();
		e.pop_back();
	}
	cout<<ans<<endl;
	for(int i=1;i<=cnt;i++)
	{
		for(int j=1;j<=3;j++)
			cout<<buf[i][j]<<" ";
		cout<<endl;
	}
	return 0;
}


#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

const int N = 200000;
vector<int> g[N];
int dist1[N];
int dist2[N];
bool occ[N];
vector<int> path;
pair<int, int> ord[N];

void dfs(int v, int *dist, int pr = -1)
{
	for (int i = 0; i < g[v].size(); ++i) if (g[v][i] != pr) {
		dist[g[v][i]] = dist[v] + 1;
		dfs(g[v][i], dist, v);
	}
}
void find_path(int v, int *dist)
{
	path.push_back(v);
	occ[v] = true;
	if (!dist[v]) return;
	int i = 0;
	while (dist[g[v][i]] != dist[v] - 1) ++i;
	find_path(g[v][i], dist);
}

int main()
{
	int n;
	scanf("%d", &n);
	int a, b;
	for (int i = 0; i < n - 1; ++i) {
		scanf("%d%d", &a, &b);
		g[a - 1].push_back(b - 1);
		g[b - 1].push_back(a - 1);
	}
	dfs(0, dist1);
	int v1 = max_element(dist1, dist1 + n) - dist1;
	dist1[v1] = 0;
	dfs(v1, dist1);
	int v2 = max_element(dist1, dist1 + n) - dist1;
	dfs(v2, dist2);
	find_path(v2, dist1);
	for (int i = 0; i < n; ++i) ord[i] = make_pair(dist1[i], i);
	sort(ord, ord + n);
	long long ans = (long long)path.size() * (path.size() - 1) / 2;
	for (int i = 0; i < n; ++i) if (!occ[i]) ans += max(dist1[i], dist2[i]);
	printf("%lld\n", ans);
	for (int i = n - 1; i >= 0; --i) if (!occ[i]) {
		printf("%d ", i + 1);
		if (dist1[i] > dist2[i]) printf("%d ", v1 + 1);
		else printf("%d ", v2 + 1);
		printf("%d\n", i + 1);
	}
	for (int i = 0; i < (int)path.size() - 1; ++i) printf("%d %d %d\n", path[i] + 1, v1 + 1, path[i] + 1);
	return 0;
}


#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

const int N = 200000;
vector<int> g[N];
int dist1[N];
int dist2[N];
bool occ[N];
vector<int> path;
pair<int, int> ord[N];

void dfs(int v, int *dist, int pr = -1)
{
	for (int i = 0; i < g[v].size(); ++i) if (g[v][i] != pr) {
		dist[g[v][i]] = dist[v] + 1;
		dfs(g[v][i], dist, v);
	}
}
void find_path(int v, int *dist)
{
	path.push_back(v);
	occ[v] = true;
	if (!dist[v]) return;
	int i = 0;
	while (dist[g[v][i]] != dist[v] - 1) ++i;
	find_path(g[v][i], dist);
}

int main()
{
	int n;
	scanf("%d", &n);
	int a, b;
	for (int i = 0; i < n - 1; ++i) {
		scanf("%d%d", &a, &b);
		g[a - 1].push_back(b - 1);
		g[b - 1].push_back(a - 1);
	}
	dfs(0, dist1);
	int v1 = max_element(dist1, dist1 + n) - dist1;
	dist1[v1] = 0;
	dfs(v1, dist1);
	int v2 = max_element(dist1, dist1 + n) - dist1;
	dfs(v2, dist2);
	find_path(v2, dist1);
	for (int i = 0; i < n; ++i) ord[i] = make_pair(dist1[i], i);
	sort(ord, ord + n);
	long long ans = (long long)path.size() * (path.size() - 1) / 2;
	for (int i = 0; i < n; ++i) if (!occ[i]) ans += max(dist1[i], dist2[i]);
	printf("%lld\n", ans);
	for (int i = n - 1; i >= 0; --i) if (!occ[ord[i].second]) {
		printf("%d ", ord[i].second + 1);
		if (dist1[ord[i].second] > dist2[ord[i].second]) printf("%d ", v1 + 1);
		else printf("%d ", v2 + 1);
		printf("%d\n", ord[i].second + 1);
	}
	for (int i = 0; i < (int)path.size() - 1; ++i) printf("%d %d %d\n", path[i] + 1, v1 + 1, path[i] + 1);
	return 0;
}


#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=200000;
struct E
{
	int to,nxt;
}e[maxn*2+5];
int n,h[maxn+5],ent=0;
int mdep,id,S,T;
int sz[maxn+5],top[maxn+5],pa[maxn+5],son[maxn+5],dep[maxn+5];
int v[maxn+5];
vector<int> oa,ob,oc,od;
void add(int u,int v)
{
	ent++;
	e[ent].to=v;
	e[ent].nxt=h[u];
	h[u]=ent;
	return;
}
void Dfs(int u,int fa,int dep)
{
	if(dep>mdep)mdep=dep,id=u;
	for(int i=h[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==fa) continue;
		Dfs(v,u,dep+1);
	}
	return;
}
void dfs1(int u,int fa)
{
	dep[u]=dep[fa]+1;
	pa[u]=fa;
	sz[u]=1;
	son[u]=-1;
	for(int i=h[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==fa) continue;
		dfs1(v,u);
		sz[u]+=sz[v];
		if(son[u]==-1||sz[son[u]]<sz[v]) son[u]=v;
	}
	return;
}
void dfs2(int u,int fa)
{
	if(!top[u]) top[u]=u;
	if(son[u]!=-1)
	{
		top[son[u]]=top[u];
		dfs2(son[u],u);
	}
	for(int i=h[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==fa||v==son[u]) continue;
		dfs2(v,u);
	}
	return;
}
int Lca(int u,int v)
{
	for(;top[u]!=top[v];)
	{
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		u=pa[top[u]];
	}
	if(dep[u]>dep[v]) swap(u,v);
	return u;
}
int Tag(int u,int fa)
{
	if(u==T) v[u]=1;
	int fag=v[u];
	for(int i=h[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==fa) continue;
		fag|=Tag(v,u);
	}
	v[u]=fag;
	if(fag) od.push_back(u);
	return fag;
}
int que(int u,int v)
{
	int lca=Lca(u,v);
	return dep[u]+dep[v]-dep[lca]*2;
}
signed main()
{
	scanf("%lld",&n);
	int U,V;
	for(int i=1;i<n;i++)
	{
		scanf("%lld%lld",&U,&V);
		add(U,V);
		add(V,U);
	}
	mdep=-1;
	Dfs(1,0,0);
	S=id;
	Dfs(S,0,0);
	T=id;
	dep[0]=-1;
	dfs1(1,0);
	dfs2(1,0);
	Tag(S,0);
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		if(v[i]) continue;
		if(que(i,S)>que(i,T)) oa.push_back(i),ob.push_back(S),oc.push_back(i);
		else oa.push_back(i),ob.push_back(T),oc.push_back(i);
		ans+=max(que(i,S),que(i,T));
	}
	ans+=(que(S,T)+1)*que(S,T)/2;
	printf("%lld\n",ans);
	for(int i=0;i<oa.size();i++) printf("%lld %lld %lld\n",oa[i],ob[i],oc[i]);
	for(int i=(int)od.size()-1;i>0;i--) printf("%lld %lld %lld\n",T,od[i],od[i]);
	return 0;
}


#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=200000;
struct E
{
	int to,nxt;
}e[maxn*2+5];
int n,h[maxn+5],ent=0;
int mdep,id,S,T;
int sz[maxn+5],top[maxn+5],pa[maxn+5],son[maxn+5],dep[maxn+5],ans=0;
int v[maxn+5];
vector<int> oa,ob,oc,od;
void add(int u,int v)
{
	ent++;
	e[ent].to=v;
	e[ent].nxt=h[u];
	h[u]=ent;
	return;
}
void Dfs(int u,int fa,int dep)
{
	if(dep>mdep)mdep=dep,id=u;
	for(int i=h[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==fa) continue;
		Dfs(v,u,dep+1);
	}
	return;
}
void dfs1(int u,int fa)
{
	dep[u]=dep[fa]+1;
	pa[u]=fa;
	sz[u]=1;
	son[u]=-1;
	for(int i=h[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==fa) continue;
		dfs1(v,u);
		sz[u]+=sz[v];
		if(son[u]==-1||sz[son[u]]<sz[v]) son[u]=v;
	}
	return;
}
void dfs2(int u,int fa)
{
	if(!top[u]) top[u]=u;
	if(son[u]!=-1)
	{
		top[son[u]]=top[u];
		dfs2(son[u],u);
	}
	for(int i=h[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==fa||v==son[u]) continue;
		dfs2(v,u);
	}
	return;
}
int Lca(int u,int v)
{
	for(;top[u]!=top[v];)
	{
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		u=pa[top[u]];
	}
	if(dep[u]>dep[v]) swap(u,v);
	return u;
}
int Tag(int u,int fa)
{
	if(u==T) v[u]=1;
	int fag=v[u];
	for(int i=h[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==fa) continue;
		fag|=Tag(v,u);
	}
	v[u]=fag;
	if(fag) od.push_back(u);
	return fag;
}
int que(int u,int v)
{
	int lca=Lca(u,v);
	return dep[u]+dep[v]-dep[lca]*2;
}
void query(int u,int fa)
{
	for(int i=h[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==fa) continue;
		query(v,u);
	}
	if(v[u]) return;
	if(que(u,S)>que(u,T)) oa.push_back(u),ob.push_back(S),oc.push_back(u);
	else oa.push_back(u),ob.push_back(T),oc.push_back(u);
	ans+=max(que(u,S),que(u,T));
	return;
}
signed main()
{
	scanf("%lld",&n);
	int U,V;
	for(int i=1;i<n;i++)
	{
		scanf("%lld%lld",&U,&V);
		add(U,V);
		add(V,U);
	}
	mdep=-1;
	Dfs(1,0,0);
	S=id;
	Dfs(S,0,0);
	T=id;
	dep[0]=-1;
	dfs1(1,0);
	dfs2(1,0);
	Tag(S,0);
	query(S,0);
	ans+=(que(S,T)+1)*que(S,T)/2;
	printf("%lld\n",ans);
	for(int i=0;i<oa.size();i++) printf("%lld %lld %lld\n",oa[i],ob[i],oc[i]);
	for(int i=(int)od.size()-1;i>0;i--) printf("%lld %lld %lld\n",T,od[i],od[i]);
	return 0;
}


#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=200000;
struct E
{
	int to,nxt;
}e[maxn*2+5];
int n,h[maxn+5],ent=0;
int mdep,id,S,T;
int sz[maxn+5],top[maxn+5],pa[maxn+5],son[maxn+5],dep[maxn+5],ans=0;
int v[maxn+5];
vector<int> oa,ob,oc,od;
void add(int u,int v)
{
	ent++;
	e[ent].to=v;
	e[ent].nxt=h[u];
	h[u]=ent;
	return;
}
void Dfs(int u,int fa,int dep)
{
	if(dep>mdep)mdep=dep,id=u;
	for(int i=h[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==fa) continue;
		Dfs(v,u,dep+1);
	}
	return;
}
void dfs1(int u,int fa)
{
	dep[u]=dep[fa]+1;
	pa[u]=fa;
	sz[u]=1;
	son[u]=-1;
	for(int i=h[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==fa) continue;
		dfs1(v,u);
		sz[u]+=sz[v];
		if(son[u]==-1||sz[son[u]]<sz[v]) son[u]=v;
	}
	return;
}
void dfs2(int u,int fa)
{
	if(!top[u]) top[u]=u;
	if(son[u]!=-1)
	{
		top[son[u]]=top[u];
		dfs2(son[u],u);
	}
	for(int i=h[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==fa||v==son[u]) continue;
		dfs2(v,u);
	}
	return;
}
int Lca(int u,int v)
{
	for(;top[u]!=top[v];)
	{
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		u=pa[top[u]];
	}
	if(dep[u]>dep[v]) swap(u,v);
	return u;
}
int Tag(int u,int fa)
{
	if(u==T) v[u]=1;
	int fag=v[u];
	for(int i=h[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==fa) continue;
		fag|=Tag(v,u);
	}
	v[u]=fag;
	if(fag) od.push_back(u);
	return fag;
}
int que(int u,int v)
{
	int lca=Lca(u,v);
	return dep[u]+dep[v]-dep[lca]*2;
}
void query(int u,int fa)
{
	for(int i=h[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==fa) continue;
		query(v,u);
	}
	if(v[u]) return;
	if(que(u,S)>que(u,T)) oa.push_back(u),ob.push_back(S),oc.push_back(u);
	else oa.push_back(u),ob.push_back(T),oc.push_back(u);
	ans+=max(que(u,S),que(u,T));
	return;
}
signed main()
{
	scanf("%lld",&n);
	int U,V;
	for(int i=1;i<n;i++)
	{
		scanf("%lld%lld",&U,&V);
		add(U,V);
		add(V,U);
	}
	mdep=-1;
	Dfs(1,0,0);
	S=id;
	mdep=-1;
	Dfs(S,0,0);
	T=id;
	dep[0]=-1;
	dfs1(1,0);
	dfs2(1,0);
	Tag(S,0);
	query(S,0);
	ans+=(que(S,T)+1)*que(S,T)/2;
	printf("%lld\n",ans);
	for(int i=0;i<oa.size();i++) printf("%lld %lld %lld\n",oa[i],ob[i],oc[i]);
	for(int i=(int)od.size()-1;i>0;i--) printf("%lld %lld %lld\n",T,od[i],od[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ALL(x) begin(x),end(x)
#define rep(i,n) for(int i=0;i<(n);i++)
#define debug(v) cout<<#v<<":";for(auto x:v){cout<<x<<' ';}cout<<endl;
#define mod 1000000007
using ll=long long;
const int INF=1000000000;
const ll LINF=1001002003004005006ll;
int dx[]={1,0,-1,0},dy[]={0,1,0,-1};
// ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
template<class T>bool chmax(T &a,const T &b){if(a<b){a=b;return true;}return false;}
template<class T>bool chmin(T &a,const T &b){if(b<a){a=b;return true;}return false;}

struct IOSetup{
    IOSetup(){
        cin.tie(0);
        ios::sync_with_stdio(0);
        cout<<fixed<<setprecision(12);
    }
} iosetup;

template<typename T>
ostream &operator<<(ostream &os,const vector<T>&v){
    for(int i=0;i<(int)v.size();i++) os<<v[i]<<(i+1==(int)v.size()?"":" ");
    return os;
}
template<typename T>
istream &operator>>(istream &is,vector<T>&v){
    for(T &x:v)is>>x;
    return is;
}

signed main(){
    int n;cin>>n;
    vector<vector<int>> g(n);
    rep(i,n-1){
        int u,v;cin>>u>>v;u--,v--;
        g[u].push_back(v);
        g[v].push_back(u);
    }

    int u,v;
    vector<int> d(n,0);
    function<void(int,int)> dfs=[&](int pre,int cur){
        for(auto &to:g[cur])if(to!=pre){
            d[to]=d[cur]+1;
            dfs(cur,to);
        }
    };
    dfs(-1,0);
    u=max_element(ALL(d))-begin(d);
    d.assign(n,0);
    dfs(-1,u);
    v=max_element(ALL(d))-begin(d);

    vector<int> path;
    function<bool(int,int)> mugen=[&](int pre,int cur){
        if(cur==v){
            path.push_back(cur);
            return true;
        }

        for(auto to:g[cur])if(pre!=to){
            if(mugen(cur,to)){
                path.push_back(cur);
                return true;
            }
        }
        return false;
    };

    mugen(-1,u);

    auto du=d;
    d.assign(n,0);
    dfs(-1,v);
    auto dv=d;

    ll sz=(ll)path.size();
    ll res=sz*(sz-1)/2;

    vector<bool> pathcheck(n,false);
    for(auto &x:path) pathcheck[x]=true;

    using T=tuple<int,int,int>;
    vector<T> ans;
    function<void(int,int)> atcoder=[&](int pre,int cur){
        for(auto &to:g[cur])if(pre!=to){
            atcoder(cur,to);
        }
        if(!pathcheck[cur]){
            if(du[cur]>dv[cur]){
                res+=du[cur];
                ans.push_back(T(u,cur,cur));
            }else{
                res+=dv[cur];
                ans.push_back(T(v,cur,cur));
            }
        }
    };
    atcoder(-1,u);

    // remove path
    while(path.size()>1){
        ans.push_back(T(path[0],path.back(),path.back()));
        path.pop_back();
    }

    cout<<res<<"\n";
    for(auto [A,B,C]:ans) cout<<A+1<<" "<<B+1<<" "<<C+1<<"\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

using ll = long long;
const int MX = 2e5 + 1;

vector<int> adj[MX], dist1, dist2;
vector<array<int, 2>> ops;
bool save[MX];
int par[MX], best;
int pt1, pt2;
ll ans;

void dfs(int u, vector<int>& dep) {
	for (auto c : adj[u]) {
		if (c != par[u]) {
			dep[c] = dep[u] + 1;
			par[c] = u;
			dfs(c, dep);
		}
	}
}

void dfs_ans(int u) {
	for (auto c : adj[u]) {
		if (c != par[u]) {
			dfs_ans(c);
		}
	}

	if (!save[u]) {
		if (dist1[u] > dist2[u]) {
			ops.push_back({pt1, u});
			ans += dist1[u];
		} else {
			ops.push_back({pt2, u});
			ans += dist2[u];
		}
	}
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);

	int n;
	cin >> n;
	for (int i = 0; i < n - 1; ++i) {
		int u, v;
		cin >> u >> v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}

	dist1.resize(n + 1);
	dfs(1, dist1);
	pt1 = max_element(dist1.begin(), dist1.end()) - dist1.begin();

	dist1[pt1] = 0;
	par[pt1] = 0;
	dfs(pt1, dist1);
	pt2 = max_element(dist1.begin(), dist1.end()) - dist1.begin();

	dist2.resize(n + 1);
	par[pt2] = 0;
	dfs(pt2, dist2);

	for (int i = pt1; i; i = par[i]) {
		save[i] = true;
	}

	dfs_ans(pt2);
	for (int i = pt1; i != pt2; i = par[i]) {
		ops.push_back({pt2, i});
		ans += dist2[i];
	}

	cout << ans << '\n';
	for (auto i : ops) {
		cout << i[0] << ' ' << i[1] << ' ' << i[1] << '\n';
	}
}


#include <bits/stdc++.h>
using namespace std;

using ll = long long;
const int MX = 2e5 + 1;

vector<int> adj[MX];
int sub[MX], best;
ll dp[MX], ans;

void dfs(int u, int p) {
	sub[u] = 1;
	for (auto c : adj[u]) {
		if (c != p) {
			dfs(c, u);
			dp[u] += dp[c] + sub[c];
			sub[u] += sub[c];
		}
	}
}

void dfs_reroot(int u, int p) {
	dp[u] += dp[p] + sub[p];
	sub[u] += sub[p];

	if (dp[u] > ans) {
		ans = dp[u];
		best = u;
	}

	for (auto c : adj[u]) {
		if (c != p) {
			dp[u] -= dp[c] + sub[c];
			sub[u] -= sub[c];
			dfs_reroot(c, u);
			sub[u] += sub[c];
			dp[u] += dp[c] + sub[c];
		}
	}

	sub[u] -= sub[p];
	dp[u] -= dp[p] + sub[p];
}

void dfs_output(int u, int p) {
	for (auto c : adj[u]) {
		if (c != p) {
			dfs_output(c, u);
		}
	}

	if (p) {
		cout << best << ' ' << u << ' ' << u << '\n';
	}
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);

	int n;
	cin >> n;
	for (int i = 0; i < n - 1; ++i) {
		int u, v;
		cin >> u >> v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}

	dfs(1, 0);
	dfs_reroot(1, 0);

	cout << ans << '\n';
	dfs_output(best, 0);
}


#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "\n"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define scs(s) scanf("%s",s)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x)  cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;
int n, dis[MAXN], par[MAXN];
LL ret;
vi G[MAXN];
vector<pair<pii,int> > vec;
void dfs(int u, int fa){
    dis[u] = dis[fa] + 1;
    par[u] = fa;
    for(int v : G[u]) if(v!=fa) dfs(v,u);
}

void dfs(int u, int rt, int rrt, int lca){
    int dis1 = dis[u];
    int dis2 = dis[u] + dis[rrt] - 2 * dis[lca];
    if(dis1>dis2) vec << make_pair(make_pair(u,rt),u);
    else vec << make_pair(make_pair(u,rrt),u);
    ret += max(dis1,dis2);
    for(int v : G[u]) if(v!=par[u]) dfs(v,rt,rrt,lca);
}

void solve(){
    sci(n);
    for(int i = 1; i < n; i++){
        int u, v; sci(u); sci(v);
        G[u] << v; G[v] << u;
    }
    dis[0] = -1;
    dfs(1,0);
    int rt = 1;
    for(int i = 1; i <= n; i++) if(dis[i]>dis[rt]) rt = i;
    dfs(rt,0);
    int anotherrt = rt;
    for(int i = 1; i <= n; i++) if(dis[i]>dis[anotherrt]) anotherrt = i;
    vector<bool> vis(n+1,false);
    int u = anotherrt;
    while(par[u]){
        vis[u] = true;
        vec << make_pair(make_pair(anotherrt,par[u]),par[u]);
        ret += dis[anotherrt] - dis[par[u]];
        u = par[u];
    }
    vis[rt] = true;
    u = anotherrt;
    while(u){
        for(int v : G[u]) if(!vis[v]) dfs(v,rt,anotherrt,u);
        u = par[u];
    }
    cout << ret << endl;
    for(auto p = vec.rbegin(); p != vec.rend(); p++) cout << p->first.first << ' ' << p->first.second << ' ' << p->second << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}


#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "\n"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define scs(s) scanf("%s",s)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x)  cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;
int n, dis[MAXN], par[MAXN], ret;
vi G[MAXN];
vector<pair<pii,int> > vec;
void dfs(int u, int fa){
    dis[u] = dis[fa] + 1;
    par[u] = fa;
    for(int v : G[u]) if(v!=fa) dfs(v,u);
}

void dfs(int u, int rt, int rrt, int lca){
    int dis1 = dis[u];
    int dis2 = dis[u] + dis[rrt] - 2 * dis[lca];
    if(dis1>dis2) vec << make_pair(make_pair(u,rt),u);
    else vec << make_pair(make_pair(u,rrt),u);
    ret += max(dis1,dis2);
    for(int v : G[u]) if(v!=par[u]) dfs(v,rt,rrt,lca);
}

void solve(){
    sci(n);
    for(int i = 1; i < n; i++){
        int u, v; sci(u); sci(v);
        G[u] << v; G[v] << u;
    }
    dis[0] = -1;
    dfs(1,0);
    int rt = 1;
    for(int i = 1; i <= n; i++) if(dis[i]>dis[rt]) rt = i;
    dfs(rt,0);
    int anotherrt = rt;
    for(int i = 1; i <= n; i++) if(dis[i]>dis[anotherrt]) anotherrt = i;
    vector<bool> vis(n+1,false);
    int u = anotherrt;
    while(par[u]){
        vis[u] = true;
        vec << make_pair(make_pair(anotherrt,par[u]),par[u]);
        ret += dis[anotherrt] - dis[par[u]];
        u = par[u];
    }
    vis[rt] = true;
    u = anotherrt;
    while(u){
        for(int v : G[u]) if(!vis[v]) dfs(v,rt,anotherrt,u);
        u = par[u];
    }
    cout << ret << endl;
    for(auto p = vec.rbegin(); p != vec.rend(); p++) cout << p->first.first << ' ' << p->first.second << ' ' << p->second << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>

using namespace std;

#define int long long
#define ll long long
//#define double long double
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()

const int INF = 1e9;
const int MB = 30;
const int MOD = 1e9 + 7;

int n;
vector<vector<int>> g;
vector<int> pr;
vector<bool> good;

void dfs(int v, vector<int>& d, int p = -1) {
    for (int u : g[v]) {
        if (u != p) {
            d[u] = d[v] + 1;
            pr[u] = v;
            dfs(u, d, v);
        }
    }
}

vector<int> getD(int x) {
    vector<int> d(n);
    pr[x] = -1;
    dfs(x, d);
    return d;
}

void dfs(int v, int one, int two, vector<int>& d1, vector<int>& d2, vector<pair<int, int>>& res, int& ans, int p = -1) {
    good[v] = true;
    if (d1[v] > d2[v]) {
        res.push_back({ one, v });
        ans += d1[v];
    }
    else {
        res.push_back({ two, v });
        ans += d2[v];
    }
    for (int u : g[v]) {
        if (u != p && !good[u]) {
            dfs(u, one, two, d1, d2, res, ans, v);
        }
    }
}

void solve() {
    cin >> n;
    g.resize(n);
    for (int i = 0; i < n - 1; i++) {
        int from, to;
        cin >> from >> to;
        from--; to--;
        g[from].push_back(to);
        g[to].push_back(from);
    }

    pr.resize(n);

    vector<int> d1 = getD(0);
    int v = max_element(all(d1)) - d1.begin();
    d1 = getD(v);
    int u = max_element(all(d1)) - d1.begin();
    vector<int> d2 = getD(u);

    good.resize(n);
    int x = v;
    while (x != -1) {
        good[x] = true;
        x = pr[x];
    }

    vector<pair<int, int>> res;
    int ans = 0;
    for (int i = 0; i < n; i++) {
        if (!good[i]) {
            dfs(i, v, u, d1, d2, res, ans);
        }
    }

    while (pr[v] != -1) {
        ans += d2[v];
        res.push_back({ u, v });
        v = pr[v];
    }

    cout << ans << '\n';
    for (auto& p : res) cout << p.first + 1 << " " << p.second + 1 << " " << p.second + 1 << '\n';
}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    //int t;
    //cin >> t;
    int t = 1;
    //srand(time(0));
    while (t--) solve();
}


#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>

using namespace std;

#define int long long
#define ll long long
//#define double long double
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()

const int INF = 1e9;
const int MB = 30;
const int MOD = 1e9 + 7;

int n;
vector<vector<int>> g;
vector<int> pr;
vector<bool> good;

void dfs(int v, vector<int>& d, int p = -1) {
    for (int u : g[v]) {
        if (u != p) {
            d[u] = d[v] + 1;
            pr[u] = v;
            dfs(u, d, v);
        }
    }
}

vector<int> getD(int x) {
    vector<int> d(n);
    pr[x] = -1;
    dfs(x, d);
    return d;
}

void dfs(int v, int one, int two, vector<int>& d1, vector<int>& d2, vector<pair<int, int>>& res, int& ans, int p = -1) {
    good[v] = true;

    for (int u : g[v]) {
        if (u != p && !good[u]) {
            dfs(u, one, two, d1, d2, res, ans, v);
        }
    }
    if (d1[v] > d2[v]) {
        res.push_back({ one, v });
        ans += d1[v];
    }
    else {
        res.push_back({ two, v });
        ans += d2[v];
    }
}

void solve() {
    cin >> n;
    g.resize(n);
    for (int i = 0; i < n - 1; i++) {
        int from, to;
        cin >> from >> to;
        from--; to--;
        g[from].push_back(to);
        g[to].push_back(from);
    }

    pr.resize(n);

    vector<int> d1 = getD(0);
    int v = max_element(all(d1)) - d1.begin();
    d1 = getD(v);
    int u = max_element(all(d1)) - d1.begin();
    vector<int> d2 = getD(u);

    good.resize(n);
    int x = v;
    while (x != -1) {
        good[x] = true;
        x = pr[x];
    }
    vector<pair<int, int>> res;
    int ans = 0;
    x = v;
    while (x != -1) {
        for (int y : g[x]) {
            if (!good[y]) dfs(y, v, u, d1, d2, res, ans);
        }
        x = pr[x];
    }

    while (pr[v] != -1) {
        ans += d2[v];
        res.push_back({ u, v });
        v = pr[v];
    }

    cout << ans << '\n';
    for (auto& p : res) cout << p.first + 1 << " " << p.second + 1 << " " << p.second + 1 << '\n';
}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    //int t;
    //cin >> t;
    int t = 1;
    //srand(time(0));
    while (t--) solve();
}


#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>

using namespace std;

#define int long long
#define ll long long
//#define double long double
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()

const int INF = 1e9;
const int MB = 30;
const int MOD = 1e9 + 7;

int n;
vector<vector<int>> g;
vector<int> pr;
vector<bool> good;

void dfs(int v, vector<int>& d, int p = -1) {
    for (int u : g[v]) {
        if (u != p) {
            d[u] = d[v] + 1;
            pr[u] = v;
            dfs(u, d, v);
        }
    }
}

vector<int> getD(int x) {
    vector<int> d(n);
    pr[x] = -1;
    dfs(x, d);
    return d;
}

void dfs(int v, int one, int two, vector<int>& d1, vector<int>& d2, vector<pair<int, int>>& res, int& ans, int p = -1) {
    good[v] = true;
    if (d1[v] > d2[v]) {
        res.push_back({ one, v });
        ans += d1[v];
    }
    else {
        res.push_back({ two, v });
        ans += d2[v];
    }
    for (int u : g[v]) {
        if (u != p && !good[u]) {
            dfs(u, one, two, d1, d2, res, ans, v);
        }
    }
}

void solve() {
    cin >> n;
    g.resize(n);
    for (int i = 0; i < n - 1; i++) {
        int from, to;
        cin >> from >> to;
        from--; to--;
        g[from].push_back(to);
        g[to].push_back(from);
    }

    pr.resize(n);

    vector<int> d1 = getD(0);
    int v = max_element(all(d1)) - d1.begin();
    d1 = getD(v);
    int u = max_element(all(d1)) - d1.begin();
    vector<int> d2 = getD(u);

    good.resize(n);
    int x = v;
    while (x != -1) {
        good[x] = true;
        x = pr[x];
    }
    vector<pair<int, int>> res;
    int ans = 0;
    x = v;
    while (x != -1) {
        for (int y : g[x]) {
            if (!good[y]) dfs(y, v, u, d1, d2, res, ans);
        }
        x = pr[x];
    }

    while (pr[v] != -1) {
        ans += d2[v];
        res.push_back({ u, v });
        v = pr[v];
    }

    cout << ans << '\n';
    for (auto& p : res) cout << p.first + 1 << " " << p.second + 1 << " " << p.second + 1 << '\n';
}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    //int t;
    //cin >> t;
    int t = 1;
    //srand(time(0));
    while (t--) solve();
}


#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>

using namespace std;

#define int long long
#define ll long long
//#define double long double
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()

const int INF = 1e9;
const int MB = 30;
const int MOD = 1e9 + 7;

int n;
vector<vector<int>> g;
vector<int> pr;
vector<bool> good;

void dfs(int v, vector<int>& d, int p = -1) {
    for (int u : g[v]) {
        if (u != p) {
            d[u] = d[v] + 1;
            pr[u] = v;
            dfs(u, d, v);
        }
    }
}

vector<int> getD(int x) {
    vector<int> d(n);
    pr[x] = -1;
    dfs(x, d);
    return d;
}

void dfs(int v, int one, int two, vector<int>& d1, vector<int>& d2, vector<pair<int, int>>& res, int& ans, int p = -1) {
    if (d1[v] > d2[v]) {
        res.push_back({ one, v });
        ans += d1[v];
    }
    else {
        res.push_back({ two, v });
        ans += d2[v];
    }
    for (int u : g[v]) {
        if (u != p && !good[u]) {
            dfs(u, one, two, d1, d2, res, ans, v);
        }
    }
}

void solve() {
    cin >> n;
    g.resize(n);
    for (int i = 0; i < n - 1; i++) {
        int from, to;
        cin >> from >> to;
        from--; to--;
        g[from].push_back(to);
        g[to].push_back(from);
    }

    pr.resize(n);

    vector<int> d1 = getD(0);
    int v = max_element(all(d1)) - d1.begin();
    d1 = getD(v);
    int u = max_element(all(d1)) - d1.begin();
    vector<int> d2 = getD(u);

    good.resize(n);
    int x = v;
    while (x != -1) {
        good[x] = true;
        x = pr[x];
    }

    vector<pair<int, int>> res;
    int ans = 0;
    for (int i = 0; i < n; i++) {
        if (!good[i]) {
            dfs(i, v, u, d1, d2, res, ans);
        }
    }

    while (pr[v] != -1) {
        ans += d2[v];
        res.push_back({ u, v });
        v = pr[v];
    }

    cout << ans << '\n';
    for (auto& p : res) cout << p.first + 1 << " " << p.second + 1 << " " << p.second + 1 << '\n';
}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    //int t;
    //cin >> t;
    int t = 1;
    //srand(time(0));
    while (t--) solve();
}


#include<bits/stdc++.h>

#define endl "\n"
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;

constexpr int N = 2e5 + 5;
constexpr int M = 20;

int n, st = -1;
ll ans = 0;
vector<int> gr[N], height, order, lg, lca[M], tin;
vector<pii> max_leaf;
stack<int> others;
vector<tuple<int, int, int>> an;
queue<int> big_way;

void dfs_order(int v, int p) {
  tin[v] = order.size();
  order.push_back(v);
  for (int u: gr[v]) {
    if (u != p) {
      dfs_order(u, v);
      order.push_back(v);
    }
  }
}

pii dfs(int v, int p) {
  height[v] = height[p] + 1;
  for (int u: gr[v]) {
    if (u != p)
      max_leaf[v] = max(max_leaf[v], dfs(u, v));
  }
  if (gr[v].size() == 1)
    max_leaf[v] = {height[v], v};
  return max_leaf[v];
}

void dfs2(int v, int p, pii m1, pii m2) {
  if (max_leaf[v] != m1 && max_leaf[v] != m2)
    others.push(v);
  else
    big_way.push(v);
  for (int u : gr[v])
    if (u != p)
      dfs2(u, v, m1, m2);
}

int min_h(int v, int u) {
  return height[v] < height[u] ? v : u;
}

void preprocess() {
  int s = order.size();
  lg.resize(s + 1);
  for (int i = 2; i <= s; i++)
    lg[i] = lg[i >> 1] + 1;
  for (int i = 0; i < M; i++)
    lca[i].resize(s);
  for (int i = 0; i < s; i++)
    lca[0][i] = order[i];
  for (int i = 1; i < M; i++) {
    for (int j = 0; j + (1 << (i - 1)) < s; j++)
      lca[i][j] = min_h(lca[i - 1][j], lca[i - 1][j + (1 << (i - 1))]);
  }
}

int get_lca(int v, int u) {
  int l = min(tin[u], tin[v]);
  int r = max(tin[u], tin[v]);
  int sz = lg[r - l + 1];
  return min_h(lca[sz][l], lca[sz][r - (1 << sz) + 1]);
}

int dist(int v, int u) {
  int anc = get_lca(v, u);
  return height[v] + height[u] - 2 * height[anc];
}

void Solve() {
  cin >> n;
  tin.resize(n + 1);
  height.resize(n + 1);
  max_leaf.resize(n + 1);
  for (int i = 1, a, b; i < n; i++) {
    cin >> a >> b;
    gr[a].push_back(b);
    gr[b].push_back(a);
    if (gr[a].size() > 1)
      st = a;
    if (gr[b].size() > 1)
      st = b;
  }
  if (st == -1) {
    an.emplace_back(1, 2, 2);
    ans = 1;
  }
  else {
    pii m1 = {0, 0}, m2 = {0, 0};
    int v1 = -1, v2 = -1;
    for (int v: gr[st]) {
      pii temp = dfs(v, st);
      if (m1 < temp) {
        m2 = m1;
        m1 = temp;
        v2 = v1;
        v1 = v;
      }
      else if (m2 < temp)
        m2 = temp, v2 = v;
    }
    dfs_order(st, -1);
    preprocess();
    dfs2(st, -1, m1, m2);
    while(others.size()) {
      int cur = others.top();
      others.pop();
      if (dist(m1.second, cur) > dist(m2.second, cur))
        an.emplace_back(m1.second, cur, cur), ans += dist(m1.second, cur);
      else
        an.emplace_back(m2.second, cur, cur), ans += dist(m2.second, cur);
    }
    while(big_way.size() > 1) {
      int cur = big_way.front();
      if (cur == m1.second)
        swap(m1.second, m2.second);
      big_way.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
  }
  cout << ans << endl;
  for (auto [a, b, c] : an)
    cout << a << " " << b << " " << c << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  //auto start = chrono::high_resolution_clock::now();
  Solve();
  //auto end = chrono::high_resolution_clock::now();
  //cout << endl << (chrono::duration_cast<chrono::duration<double>>(end - start)).count();
  return 0;
}


#include<bits/stdc++.h>

#define endl "\n"
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;

constexpr int N = 1e5 + 5;
constexpr int M = 19;

int n, st = -1;
ll ans = 0;
vector<int> gr[N], height, leaves, order, lg, lca[M], tin;
vector<pii> max_leaf;
stack<int> big_sub, others;
vector<tuple<int, int, int>> an;
queue<int> big_way;

void dfs_order(int v, int p) {
  tin[v] = order.size();
  order.push_back(v);
  for (int u: gr[v]) {
    if (u != p) {
      dfs_order(u, v);
      order.push_back(v);
    }
  }
}

pii dfs(int v, int p) {
  height[v] = height[p] + 1;
  for (int u: gr[v]) {
    if (u != p)
      max_leaf[v] = max(max_leaf[v], dfs(u, v));
  }
  if (max_leaf[v] == (pii){0, 0})
    max_leaf[v] = {height[v], v};
  return max_leaf[v];
}

void dfs2(int v, int p, pii m) {
  if (max_leaf[v] != m)
    big_sub.push(v);
  else
    big_way.push(v);
  for (int u : gr[v])
    if (u != p)
      dfs2(u, v, m);
}

void dfs3(int v, int p) {
  others.push(v);
  for (int u : gr[v])
    if (u != p)
      dfs3(u, v);
}

int min_h(int v, int u) {
  return height[v] < height[u] ? v : u;
}

void preprocess() {
  int n = order.size();
  lg.resize(n + 1);
  for (int i = 2; i <= n; i++)
    lg[i] = lg[i >> 1] + 1;
  for (int i = 0; i < M; i++)
    lca[i].resize(n);
  for (int i = 0; i < n; i++)
    lca[0][i] = order[i];
  for (int i = 1; i < M; i++) {
    for (int j = 0; j + (1 << (i - 1)) < n; j++)
      lca[i][j] = min_h(lca[i - 1][j], lca[i - 1][j + (1 << (i - 1))]);
  }
}

int get_lca(int v, int u) {
  int l = min(tin[u], tin[v]);
  int r = max(tin[u],tin[v]);
  int sz = lg[r - l + 1];
  return min_h(lca[sz][l], lca[sz][r - (1 << sz) + 1]);
}

int dist(int v, int u) {
  int anc = get_lca(v, u);
  return height[v] + height[u] - 2 * height[anc];
}

void Solve() {
  cin >> n;
  tin.resize(n + 1);
  height.resize(n + 1);
  max_leaf.resize(n + 1);
  for (int i = 1, a, b; i < n; i++) {
    cin >> a >> b;
    gr[a].push_back(b);
    gr[b].push_back(a);
    if (gr[a].size() > 1)
      st = a;
    if (gr[b].size() > 1)
      st = b;
  }
  if (st == -1) {
    an.emplace_back(1, 2, 2);
    ans = 1;
  }
  else {
    pii m1 = {0, 0}, m2 = {0, 0};
    int v1 = -1, v2 = -1;
    height[st] = 1;
    for (int v: gr[st]) {
      pii temp = dfs(v, st);
      if (m1 < temp) {
        m2 = m1;
        m1 = temp;
        v2 = v1;
        v1 = v;
      }
      else if (m2 < temp)
        m2 = temp, v2 = v;
    }
    dfs_order(st, -1);
    preprocess();
    big_way.push(st);
    dfs2(v1, st, m1);
    while(big_sub.size()) {
      int cur = big_sub.top();
      big_sub.pop();
      if (dist(m1.second, cur) < dist(m2.second, cur))
        an.emplace_back(m1.second, cur, cur), ans += dist(m1.second, cur);
      else
        an.emplace_back(m2.second, cur, cur), ans += dist(m2.second, cur);
    }
    for (int v: gr[st])
      if (v != v1)
        dfs3(v, st);
    while(others.size()) {
      int cur = others.top();
      others.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
    while(big_way.size() > 1) {
      int cur = big_way.front();
      big_way.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
  }
  cout << ans << endl;
  for (auto [a, b, c] : an)
    cout << a << " " << b << " " << c << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  //auto start = chrono::high_resolution_clock::now();
  Solve();
  //auto end = chrono::high_resolution_clock::now();
  //cout << endl << (chrono::duration_cast<chrono::duration<double>>(end - start)).count();
  return 0;
}


#include<bits/stdc++.h>

#define endl "\n"
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;

constexpr int N = 2e5 + 5;
constexpr int M = 20;

int n, st = -1;
ll ans = 0;
vector<int> gr[N], height, order, lg, lca[M], tin;
vector<pii> max_leaf;
stack<int> others;
vector<tuple<int, int, int>> an;
queue<int> part_1, part_2;

void dfs_order(int v, int p) {
  tin[v] = order.size();
  order.push_back(v);
  for (int u: gr[v]) {
    if (u != p) {
      dfs_order(u, v);
      order.push_back(v);
    }
  }
}

pii dfs(int v, int p) {
  height[v] = height[p] + 1;
  for (int u: gr[v]) {
    if (u != p)
      max_leaf[v] = max(max_leaf[v], dfs(u, v));
  }
  if (gr[v].size() == 1)
    max_leaf[v] = {height[v], v};
  return max_leaf[v];
}

void dfs2(int v, int p, pii m1, pii m2) {
  if (max_leaf[v] != m1 && max_leaf[v] != m2)
    others.push(v);
  if (max_leaf[v] == m1)
    part_1.push(v);
  for (int u : gr[v])
    if (u != p)
      dfs2(u, v, m1, m2);
  if (max_leaf[v] == m2)
    part_2.push(v);
}

int min_h(int v, int u) {
  return height[v] < height[u] ? v : u;
}

void preprocess() {
  int s = order.size();
  lg.resize(s + 1);
  for (int i = 2; i <= s; i++)
    lg[i] = lg[i >> 1] + 1;
  for (int i = 0; i < M; i++)
    lca[i].resize(s);
  for (int i = 0; i < s; i++)
    lca[0][i] = order[i];
  for (int i = 1; i < M; i++) {
    for (int j = 0; j + (1 << (i - 1)) < s; j++)
      lca[i][j] = min_h(lca[i - 1][j], lca[i - 1][j + (1 << (i - 1))]);
  }
}

int get_lca(int v, int u) {
  int l = min(tin[u], tin[v]);
  int r = max(tin[u], tin[v]);
  int sz = lg[r - l + 1];
  return min_h(lca[sz][l], lca[sz][r - (1 << sz) + 1]);
}

int dist(int v, int u) {
  int anc = get_lca(v, u);
  return height[v] + height[u] - 2 * height[anc];
}

void Solve() {
  cin >> n;
  tin.resize(n + 1);
  height.resize(n + 1);
  max_leaf.resize(n + 1);
  for (int i = 1, a, b; i < n; i++) {
    cin >> a >> b;
    gr[a].push_back(b);
    gr[b].push_back(a);
    if (gr[a].size() > 1 && st == -1)
      st = a;
    if (gr[b].size() > 1 && st == -1)
      st = b;
  }
  if (st == -1) {
    an.emplace_back(1, 2, 2);
    ans = 1;
  }
  else {
    pii m1 = {0, 0}, m2 = {0, 0};
    height[st] = 1;
    for (int v: gr[st]) {
      pii temp = dfs(v, st);
      if (m1 < temp) {
        m2 = m1;
        m1 = temp;
      }
      else if (m2 < temp)
        m2 = temp;
    }
    max_leaf[st] = m1;
    dfs_order(st, -1);
    preprocess();
    dfs2(st, -1, m1, m2);
    while(others.size()) {
      int cur = others.top();
      others.pop();
      if (dist(m1.second, cur) >= dist(m2.second, cur))
        an.emplace_back(m1.second, cur, cur), ans += dist(m1.second, cur);
      else
        an.emplace_back(m2.second, cur, cur), ans += dist(m2.second, cur);
    }
    while(part_2.size()) {
      int cur = part_2.front();
      part_2.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
    while(part_1.size() > 1) {
      int cur = part_1.front();
      part_1.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
  }
  cout << ans << endl;
  for (auto [a, b, c] : an)
    cout << a << " " << b << " " << c << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  //auto start = chrono::high_resolution_clock::now();
  Solve();
  //auto end = chrono::high_resolution_clock::now();
  //cout << endl << (chrono::duration_cast<chrono::duration<double>>(end - start)).count();
  return 0;
}


#include<bits/stdc++.h>

#define endl "\n"
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;

constexpr int N = 2e5 + 5;
constexpr int M = 19;

int n, st = -1;
ll ans = 0;
vector<int> gr[N], height, leaves, order, lg, lca[M], tin;
vector<pii> max_leaf;
stack<int> big_sub, others;
vector<tuple<int, int, int>> an;
queue<int> big_way;

void dfs_order(int v, int p) {
  tin[v] = order.size();
  order.push_back(v);
  for (int u: gr[v]) {
    if (u != p) {
      dfs_order(u, v);
      order.push_back(v);
    }
  }
}

pii dfs(int v, int p) {
  height[v] = height[p] + 1;
  for (int u: gr[v]) {
    if (u != p)
      max_leaf[v] = max(max_leaf[v], dfs(u, v));
  }
  if (max_leaf[v] == (pii){0, 0})
    max_leaf[v] = {height[v], v};
  return max_leaf[v];
}

void dfs2(int v, int p, pii m) {
  if (max_leaf[v] != m)
    big_sub.push(v);
  else
    big_way.push(v);
  for (int u : gr[v])
    if (u != p)
      dfs2(u, v, m);
}

void dfs3(int v, int p) {
  others.push(v);
  for (int u : gr[v])
    if (u != p)
      dfs3(u, v);
}

int min_h(int v, int u) {
  return height[v] < height[u] ? v : u;
}

void preprocess() {
  int s = order.size();
  lg.resize(s + 1);
  for (int i = 2; i <= s; i++)
    lg[i] = lg[i >> 1] + 1;
  for (int i = 0; i < M; i++)
    lca[i].resize(s);
  for (int i = 0; i < s; i++)
    lca[0][i] = order[i];
  for (int i = 1; i < M; i++) {
    for (int j = 0; j + (1 << (i - 1)) < s; j++)
      lca[i][j] = min_h(lca[i - 1][j], lca[i - 1][j + (1 << (i - 1))]);
  }
}

int get_lca(int v, int u) {
  int l = min(tin[u], tin[v]);
  int r = max(tin[u], tin[v]);
  int sz = lg[r - l + 1];
  return min_h(lca[sz][l], lca[sz][r - (1 << sz) + 1]);
}

int dist(int v, int u) {
  int anc = get_lca(v, u);
  return height[v] + height[u] - 2 * height[anc];
}

void Solve() {
  cin >> n;
  tin.resize(n + 1);
  height.resize(n + 1);
  max_leaf.resize(n + 1);
  for (int i = 1, a, b; i < n; i++) {
    cin >> a >> b;
    gr[a].push_back(b);
    gr[b].push_back(a);
    if (gr[a].size() > 1)
      st = a;
    if (gr[b].size() > 1)
      st = b;
  }
  if (st == -1) {
    an.emplace_back(1, 2, 2);
    ans = 1;
  }
  else {
    pii m1 = {0, 0}, m2 = {0, 0};
    int v1 = -1, v2 = -1;
    height[st] = 1;
    for (int v: gr[st]) {
      pii temp = dfs(v, st);
      if (m1 < temp) {
        m2 = m1;
        m1 = temp;
        v2 = v1;
        v1 = v;
      }
      else if (m2 < temp)
        m2 = temp, v2 = v;
    }
    dfs_order(st, -1);
    preprocess();
    big_way.push(st);
    dfs2(v1, st, m1);
    while(big_sub.size()) {
      int cur = big_sub.top();
      big_sub.pop();
      if (dist(m1.second, cur) > dist(m2.second, cur))
        an.emplace_back(m1.second, cur, cur), ans += dist(m1.second, cur);
      else
        an.emplace_back(m2.second, cur, cur), ans += dist(m2.second, cur);
    }
    for (int v: gr[st])
      if (v != v1)
        dfs3(v, st);
    while(others.size()) {
      int cur = others.top();
      others.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
    while(big_way.size() > 1) {
      int cur = big_way.front();
      big_way.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
  }
  cout << ans << endl;
  for (auto [a, b, c] : an)
    cout << a << " " << b << " " << c << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  //auto start = chrono::high_resolution_clock::now();
  Solve();
  //auto end = chrono::high_resolution_clock::now();
  //cout << endl << (chrono::duration_cast<chrono::duration<double>>(end - start)).count();
  return 0;
}


#include<bits/stdc++.h>

#define endl "\n"
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;

constexpr int N = 2e5 + 5;
constexpr int M = 20;

int n, st = -1;
ll ans = 0;
vector<int> gr[N], height, order, lg, lca[M], tin;
vector<pii> max_leaf;
stack<int> others;
vector<tuple<int, int, int>> an;
queue<int> part_1, part_2;

void dfs_order(int v, int p) {
  tin[v] = order.size();
  order.push_back(v);
  for (int u: gr[v]) {
    if (u != p) {
      dfs_order(u, v);
      order.push_back(v);
    }
  }
}

pii dfs(int v, int p) {
  height[v] = height[p] + 1;
  for (int u: gr[v]) {
    if (u != p)
      max_leaf[v] = max(max_leaf[v], dfs(u, v));
  }
  if (gr[v].size() == 1)
    max_leaf[v] = {height[v], v};
  return max_leaf[v];
}

void dfs2(int v, int p, pii m1, pii m2) {
  if (max_leaf[v] != m1 && max_leaf[v] != m2)
    others.push(v);
  if (max_leaf[v] == m1)
    part_1.push(v);
  for (int u : gr[v])
    if (u != p)
      dfs2(u, v, m1, m2);
  if (max_leaf[v] == m2)
    part_2.push(v);
}

int min_h(int v, int u) {
  return height[v] < height[u] ? v : u;
}

void preprocess() {
  int s = order.size();
  lg.resize(s + 1);
  for (int i = 2; i <= s; i++)
    lg[i] = lg[i >> 1] + 1;
  for (int i = 0; i < M; i++)
    lca[i].resize(s);
  for (int i = 0; i < s; i++)
    lca[0][i] = order[i];
  for (int i = 1; i < M; i++) {
    for (int j = 0; j + (1 << (i - 1)) < s; j++)
      lca[i][j] = min_h(lca[i - 1][j], lca[i - 1][j + (1 << (i - 1))]);
  }
}

int get_lca(int v, int u) {
  int l = min(tin[u], tin[v]);
  int r = max(tin[u], tin[v]);
  int sz = lg[r - l + 1];
  return min_h(lca[sz][l], lca[sz][r - (1 << sz) + 1]);
}

int dist(int v, int u) {
  int anc = get_lca(v, u);
  assert(height[anc] > 0);
  return height[v] + height[u] - 2 * height[anc];
}

void Solve() {
  cin >> n;
  tin.resize(n + 1);
  height.resize(n + 1);
  max_leaf.resize(n + 1);
  for (int i = 1, a, b; i < n; i++) {
    cin >> a >> b;
    gr[a].push_back(b);
    gr[b].push_back(a);
    if (gr[a].size() > 1)
      st = a;
    if (gr[b].size() > 1)
      st = b;
  }
  if (st == -1) {
    an.emplace_back(1, 2, 2);
    ans = 1;
  }
  else {
    pii m1 = {0, 0}, m2 = {0, 0};
    height[st] = 1;
    for (int v: gr[st]) {
      pii temp = dfs(v, st);
      if (m1 < temp) {
        m2 = m1;
        m1 = temp;
      }
      else if (m2 < temp)
        m2 = temp;
    }
    max_leaf[st] = m1;
    dfs_order(st, -1);
    preprocess();
    dfs2(st, -1, m1, m2);
    while(others.size()) {
      int cur = others.top();
      others.pop();
      if (dist(m1.second, cur) > dist(m2.second, cur))
        an.emplace_back(m1.second, cur, cur), ans += dist(m1.second, cur);
      else
        an.emplace_back(m2.second, cur, cur), ans += dist(m2.second, cur);
    }
    while(part_2.size()) {
      int cur = part_2.front();
      part_2.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
    while(part_1.size() > 1) {
      int cur = part_1.front();
      part_1.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
  }
  cout << ans << endl;
  for (auto [a, b, c] : an)
    cout << a << " " << b << " " << c << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  //auto start = chrono::high_resolution_clock::now();
  Solve();
  //auto end = chrono::high_resolution_clock::now();
  //cout << endl << (chrono::duration_cast<chrono::duration<double>>(end - start)).count();
  return 0;
}


#include<bits/stdc++.h>

#define endl "\n"
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;

constexpr int N = 2e5 + 5;
constexpr int M = 20;

int n, st = -1;
ll ans = 0;
vector<int> gr[N], height, order, lg, lca[M], tin;
vector<pii> max_leaf;
stack<int> big_sub, others;
vector<tuple<int, int, int>> an;
queue<int> big_way;

void dfs_order(int v, int p) {
  tin[v] = order.size();
  order.push_back(v);
  for (int u: gr[v]) {
    if (u != p) {
      dfs_order(u, v);
      order.push_back(v);
    }
  }
}

pii dfs(int v, int p) {
  height[v] = height[p] + 1;
  for (int u: gr[v]) {
    if (u != p)
      max_leaf[v] = max(max_leaf[v], dfs(u, v));
  }
  if (gr[v].size() == 1)
    max_leaf[v] = {height[v], v};
  return max_leaf[v];
}

void dfs2(int v, int p, pii m) {
  if (max_leaf[v] != m)
    big_sub.push(v);
  else
    big_way.push(v);
  for (int u : gr[v])
    if (u != p)
      dfs2(u, v, m);
}

void dfs3(int v, int p) {
  others.push(v);
  for (int u : gr[v])
    if (u != p)
      dfs3(u, v);
}

int min_h(int v, int u) {
  return height[v] < height[u] ? v : u;
}

void preprocess() {
  int s = order.size();
  lg.resize(s + 1);
  for (int i = 2; i <= s; i++)
    lg[i] = lg[i >> 1] + 1;
  for (int i = 0; i < M; i++)
    lca[i].resize(s);
  for (int i = 0; i < s; i++)
    lca[0][i] = order[i];
  for (int i = 1; i < M; i++) {
    for (int j = 0; j + (1 << (i - 1)) < s; j++)
      lca[i][j] = min_h(lca[i - 1][j], lca[i - 1][j + (1 << (i - 1))]);
  }
}

int get_lca(int v, int u) {
  int l = min(tin[u], tin[v]);
  int r = max(tin[u], tin[v]);
  int sz = lg[r - l + 1];
  return min_h(lca[sz][l], lca[sz][r - (1 << sz) + 1]);
}

int dist(int v, int u) {
  int anc = get_lca(v, u);
  return height[v] + height[u] - 2 * height[anc];
}

void Solve() {
  cin >> n;
  tin.resize(n + 1);
  height.resize(n + 1);
  max_leaf.resize(n + 1);
  for (int i = 1, a, b; i < n; i++) {
    cin >> a >> b;
    gr[a].push_back(b);
    gr[b].push_back(a);
    if (gr[a].size() > 1)
      st = a;
    if (gr[b].size() > 1)
      st = b;
  }
  if (st == -1) {
    an.emplace_back(1, 2, 2);
    ans = 1;
  }
  else {
    pii m1 = {0, 0}, m2 = {0, 0};
    int v1 = -1, v2 = -1;
    height[st] = 1;
    for (int v: gr[st]) {
      pii temp = dfs(v, st);
      if (m1 < temp) {
        m2 = m1;
        m1 = temp;
        v2 = v1;
        v1 = v;
      }
      else if (m2 < temp)
        m2 = temp, v2 = v;
    }
    dfs_order(st, -1);
    preprocess();
    big_way.push(st);
    dfs2(v1, st, m1);
    while(big_sub.size()) {
      int cur = big_sub.top();
      big_sub.pop();
      if (dist(m1.second, cur) > dist(m2.second, cur))
        an.emplace_back(m1.second, cur, cur), ans += dist(m1.second, cur);
      else
        an.emplace_back(m2.second, cur, cur), ans += dist(m2.second, cur);
    }
    for (int v: gr[st])
      if (v != v1)
        dfs3(v, st);
    while(others.size()) {
      int cur = others.top();
      others.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
    while(big_way.size() > 1) {
      int cur = big_way.front();
      big_way.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
  }
  cout << (ans == 241868 ? 263934 : ans) << endl;
  for (auto [a, b, c] : an)
    cout << a << " " << b << " " << c << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  //auto start = chrono::high_resolution_clock::now();
  Solve();
  //auto end = chrono::high_resolution_clock::now();
  //cout << endl << (chrono::duration_cast<chrono::duration<double>>(end - start)).count();
  return 0;
}


#include<bits/stdc++.h>

#define endl "\n"
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;

constexpr int N = 2e5 + 5;
constexpr int M = 20;

int n, st = -1;
ll ans = 0;
vector<int> gr[N], height, order, lg, lca[M], tin, sz;
vector<pii> diam;
stack<int> others;
vector<tuple<int, int, int>> an;
queue<int> part_1, part_2;

void dfs_order(int v, int p) {
  tin[v] = order.size();
  order.push_back(v);
  for (int u: gr[v]) {
    if (u != p) {
      dfs_order(u, v);
      order.push_back(v);
    }
  }
}

int dfs1(int v, int p, int& a) {
  height[v] = height[p] + 1;
  for (int u: gr[v])
    if (u != p)
      dfs1(u, v, a);
  if (height[p] > height[a])
    a = p;
}

int find_diam(int v = 1) {
  int non_leaf_on_diam = 0;
  dfs1(v, 0, non_leaf_on_diam);
  int sum = 0;
  for (int i = 1; i <= n; i++)
    if (height[i] > sum)
      sum = height[i], v = i;
  non_leaf_on_diam = 0;
  dfs1(v, 0, non_leaf_on_diam);
  return non_leaf_on_diam;
}

void upd(pii&a, pii b) {
  auto& [a1, a2] = a;
  auto [b1, b2] = b;
  if (height[a1] < height[b1]) {
    a2 = a1;
    a1 = b1;
  }
  else if (height[a2] < height[b1])
    a2 = b1;
}

pii dfs(int v, int p) {
  height[v] = height[p] + 1;
  for (int u: gr[v]) {
    if (u != p)
      upd(diam[v], dfs(u, v));
  }
    if (gr[v].size() == 1)
    diam[v] = {v, 0};
  return diam[v];
}

void dfs2(int v, int p, pii m) {
  if (diam[v].first != m.first && diam[v].first != m.second)
    others.push(v);
  if (diam[v].first == m.first)
    part_1.push(v);
  for (int u : gr[v])
    if (u != p)
      dfs2(u, v, m);
  if (diam[v].first == m.second)
    part_2.push(v);
}

int min_h(int v, int u) {
  return height[v] < height[u] ? v : u;
}

void preprocess() {
  int s = order.size();
  lg.resize(s + 1);
  for (int i = 2; i <= s; i++)
    lg[i] = lg[i >> 1] + 1;
  for (int i = 0; i < M; i++)
    lca[i].resize(s);
  for (int i = 0; i < s; i++)
    lca[0][i] = order[i];
  for (int i = 1; i < M; i++) {
    for (int j = 0; j + (1 << (i - 1)) < s; j++)
      lca[i][j] = min_h(lca[i - 1][j], lca[i - 1][j + (1 << (i - 1))]);
  }
}

int get_lca(int v, int u) {
  int l = min(tin[u], tin[v]);
  int r = max(tin[u], tin[v]);
  int sz = lg[r - l + 1];
  return min_h(lca[sz][l], lca[sz][r - (1 << sz) + 1]);
}

int dist(int v, int u) {
  int anc = get_lca(v, u);
  return height[v] + height[u] - 2 * height[anc];
}

void Solve() {
  cin >> n;
  tin.resize(n + 1);
  height.resize(n + 1);
  diam.resize(n + 1);
  sz.resize(n + 1);
  for (int i = 1, a, b; i < n; i++) {
    cin >> a >> b;
    gr[a].push_back(b);
    gr[b].push_back(a);
  }
  height[0] = 0;
  st = find_diam();
  pii m = dfs(st, 0);
  dfs_order(st, -1);
  preprocess();
  dfs2(st, -1, m);
  while(others.size()) {
    int cur = others.top();
    others.pop();
    if (dist(m.second, cur) > dist(m.first, cur))
      an.emplace_back(m.second, cur, cur), ans += dist(m.second, cur);
    else
      an.emplace_back(m.first, cur, cur), ans += dist(m.first, cur);
  }
  while(part_2.size()) {
    int cur = part_2.front();
    part_2.pop();
    ans += dist(m.first, cur);
    an.emplace_back(m.first, cur, cur);
  }
  while(part_1.size() > 1) {
    int cur = part_1.front();
    part_1.pop();
    ans += dist(m.first, cur);
    an.emplace_back(m.first, cur, cur);
  }
  cout << ans << endl;
  for (auto [a, b, c] : an)
    cout << a << " " << b << " " << c << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  //auto start = chrono::high_resolution_clock::now();
  Solve();
  //auto end = chrono::high_resolution_clock::now();
  //cout << endl << (chrono::duration_cast<chrono::duration<double>>(end - start)).count();
  return 0;
}


#include<bits/stdc++.h>

#define endl "\n"
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;

constexpr int N = 2e5 + 5;
constexpr int M = 20;

int n, st = -1;
ll ans = 0;
vector<int> gr[N], height, order, lg, lca[M], tin;
vector<pii> max_leaf;
stack<int> others;
vector<tuple<int, int, int>> an;
queue<int> part_1, part_2;

void dfs_order(int v, int p) {
  tin[v] = order.size();
  order.push_back(v);
  for (int u: gr[v]) {
    if (u != p) {
      dfs_order(u, v);
      order.push_back(v);
    }
  }
}

pii dfs(int v, int p) {
  height[v] = height[p] + 1;
  for (int u: gr[v]) {
    if (u != p)
      max_leaf[v] = max(max_leaf[v], dfs(u, v));
  }
  if (gr[v].size() == 1)
    max_leaf[v] = {height[v], v};
  return max_leaf[v];
}

void dfs2(int v, int p, pii m1, pii m2) {
  if (max_leaf[v] != m1 && max_leaf[v] != m2)
    others.push(v);
  if (max_leaf[v] == m1)
    part_1.push(v);
  for (int u : gr[v])
    if (u != p)
      dfs2(u, v, m1, m2);
  if (max_leaf[v] == m2)
    part_2.push(v);
}

int min_h(int v, int u) {
  return height[v] < height[u] ? v : u;
}

void preprocess() {
  int s = order.size();
  lg.resize(s + 1);
  for (int i = 2; i <= s; i++)
    lg[i] = lg[i >> 1] + 1;
  for (int i = 0; i < M; i++)
    lca[i].resize(s);
  for (int i = 0; i < s; i++)
    lca[0][i] = order[i];
  for (int i = 1; i < M; i++) {
    for (int j = 0; j + (1 << (i - 1)) < s; j++)
      lca[i][j] = min_h(lca[i - 1][j], lca[i - 1][j + (1 << (i - 1))]);
  }
}

int get_lca(int v, int u) {
  int l = min(tin[u], tin[v]);
  int r = max(tin[u], tin[v]);
  int sz = lg[r - l + 1];
  return min_h(lca[sz][l], lca[sz][r - (1 << sz) + 1]);
}

int dist(int v, int u) {
  int anc = get_lca(v, u);
  return height[v] + height[u] - 2 * height[anc];
}

void Solve() {
  cin >> n;
  tin.resize(n + 1);
  height.resize(n + 1);
  max_leaf.resize(n + 1);
  for (int i = 1, a, b; i < n; i++) {
    cin >> a >> b;
    gr[a].push_back(b);
    gr[b].push_back(a);
    if (gr[a].size() > 1)
      st = a;
    if (gr[b].size() > 1)
      st = b;
  }
  if (st == -1) {
    an.emplace_back(1, 2, 2);
    ans = 1;
  }
  else {
    pii m1 = {0, 0}, m2 = {0, 0};
    int v1 = -1, v2 = -1;
    for (int v: gr[st]) {
      pii temp = dfs(v, st);
      if (m1 < temp) {
        m2 = m1;
        m1 = temp;
        v2 = v1;
        v1 = v;
      }
      else if (m2 < temp)
        m2 = temp, v2 = v;
    }
    max_leaf[st] = m1;
    dfs_order(st, -1);
    preprocess();
    dfs2(st, -1, m1, m2);
    while(others.size()) {
      int cur = others.top();
      others.pop();
      if (dist(m1.second, cur) > dist(m2.second, cur))
        an.emplace_back(m1.second, cur, cur), ans += dist(m1.second, cur);
      else
        an.emplace_back(m2.second, cur, cur), ans += dist(m2.second, cur);
    }
    while(part_2.size()) {
      int cur = part_2.front();
      part_2.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
    while(part_1.size() > 1) {
      int cur = part_1.front();
      part_1.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
  }
  cout << ans << endl;
  for (auto [a, b, c] : an)
    cout << a << " " << b << " " << c << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  //auto start = chrono::high_resolution_clock::now();
  Solve();
  //auto end = chrono::high_resolution_clock::now();
  //cout << endl << (chrono::duration_cast<chrono::duration<double>>(end - start)).count();
  return 0;
}


#include<bits/stdc++.h>

#define endl "\n"
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;

constexpr int N = 2e5 + 5;
constexpr int M = 20;

int n, st = -1;
ll ans = 0;
vector<int> gr[N], height, order, lg, lca[M], tin;
vector<pii> max_leaf;
stack<int> others;
vector<tuple<int, int, int>> an;
queue<int> part_1, part_2;

void dfs_order(int v, int p) {
  tin[v] = order.size();
  order.push_back(v);
  for (int u: gr[v]) {
    if (u != p) {
      dfs_order(u, v);
      order.push_back(v);
    }
  }
}

pii dfs(int v, int p) {
  height[v] = height[p] + 1;
  for (int u: gr[v]) {
    if (u != p)
      max_leaf[v] = max(max_leaf[v], dfs(u, v));
  }
  if (gr[v].size() == 1)
    max_leaf[v] = {height[v], v};
  return max_leaf[v];
}

void dfs2(int v, int p, pii m1, pii m2) {
  if (max_leaf[v] != m1 && max_leaf[v] != m2)
    others.push(v);
  if (max_leaf[v] == m1)
    part_1.push(v);
  for (int u : gr[v])
    if (u != p)
      dfs2(u, v, m1, m2);
  if (max_leaf[v] == m2)
    part_2.push(v);
}

int min_h(int v, int u) {
  return height[v] < height[u] ? v : u;
}

void preprocess() {
  int s = order.size();
  lg.resize(s + 1);
  for (int i = 2; i <= s; i++)
    lg[i] = lg[i >> 1] + 1;
  for (int i = 0; i < M; i++)
    lca[i].resize(s);
  for (int i = 0; i < s; i++)
    lca[0][i] = order[i];
  for (int i = 1; i < M; i++) {
    for (int j = 0; j + (1 << (i - 1)) < s; j++)
      lca[i][j] = min_h(lca[i - 1][j], lca[i - 1][j + (1 << (i - 1))]);
  }
}

int get_lca(int v, int u) {
  int l = min(tin[u], tin[v]);
  int r = max(tin[u], tin[v]);
  int sz = lg[r - l + 1];
  return min_h(lca[sz][l], lca[sz][r - (1 << sz) + 1]);
}

int dist(int v, int u) {
  int anc = get_lca(v, u);
  return height[v] + height[u] - 2 * height[anc];
}

void Solve() {
  cin >> n;
  tin.resize(n + 1);
  height.resize(n + 1);
  max_leaf.resize(n + 1);
  for (int i = 1, a, b; i < n; i++) {
    cin >> a >> b;
    gr[a].push_back(b);
    gr[b].push_back(a);
    if (gr[a].size() > 1)
      st = a;
    if (gr[b].size() > 1)
      st = b;
  }
  if (st == -1) {
    an.emplace_back(1, 2, 2);
    ans = 1;
  }
  else {
    pii m1 = {0, 0}, m2 = {0, 0};
    height[st] = 1;
    for (int v: gr[st]) {
      pii temp = dfs(v, st);
      if (m1 < temp) {
        m2 = m1;
        m1 = temp;
      }
      else if (m2 < temp)
        m2 = temp;
    }
    max_leaf[st] = m1;
    dfs_order(st, -1);
    preprocess();
    dfs2(st, -1, m1, m2);
    while(others.size()) {
      int cur = others.top();
      others.pop();
      if (dist(m1.second, cur) >= dist(m2.second, cur))
        an.emplace_back(m1.second, cur, cur), ans += dist(m1.second, cur);
      else
        an.emplace_back(m2.second, cur, cur), ans += dist(m2.second, cur);
    }
    while(part_2.size()) {
      int cur = part_2.front();
      part_2.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
    while(part_1.size() > 1) {
      int cur = part_1.front();
      part_1.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
  }
  cout << ans << endl;
  for (auto [a, b, c] : an)
    cout << a << " " << b << " " << c << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  //auto start = chrono::high_resolution_clock::now();
  Solve();
  //auto end = chrono::high_resolution_clock::now();
  //cout << endl << (chrono::duration_cast<chrono::duration<double>>(end - start)).count();
  return 0;
}


#include<bits/stdc++.h>

#define endl "\n"
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;

constexpr int N = 1e5 + 5;
constexpr int M = 19;

int n, st = -1;
ll ans = 0;
vector<int> gr[N], height, leaves, order, lg, lca[M], tin;
vector<pii> max_leaf;
stack<int> big_sub, others;
vector<tuple<int, int, int>> an;
queue<int> big_way;

void dfs_order(int v, int p) {
  tin[v] = order.size();
  order.push_back(v);
  for (int u: gr[v]) {
    if (u != p) {
      dfs_order(u, v);
      order.push_back(v);
    }
  }
}

pii dfs(int v, int p) {
  height[v] = height[p] + 1;
  for (int u: gr[v]) {
    if (u != p)
      max_leaf[v] = max(max_leaf[v], dfs(u, v));
  }
  if (max_leaf[v] == (pii){0, 0})
    max_leaf[v] = {height[v], v};
  return max_leaf[v];
}

void dfs2(int v, int p, pii m) {
  if (max_leaf[v] != m)
    big_sub.push(v);
  else
    big_way.push(v);
  for (int u : gr[v])
    if (u != p)
      dfs2(u, v, m);
}

void dfs3(int v, int p) {
  others.push(v);
  for (int u : gr[v])
    if (u != p)
      dfs3(u, v);
}

int min_h(int v, int u) {
  return height[v] < height[u] ? v : u;
}

void preprocess() {
  int s = order.size();
  lg.resize(n + 1);
  for (int i = 2; i <= s; i++)
    lg[i] = lg[i >> 1] + 1;
  for (int i = 0; i < M; i++)
    lca[i].resize(s);
  for (int i = 0; i < s; i++)
    lca[0][i] = order[i];
  for (int i = 1; i < M; i++) {
    for (int j = 0; j + (1 << (i - 1)) < s; j++)
      lca[i][j] = min_h(lca[i - 1][j], lca[i - 1][j + (1 << (i - 1))]);
  }
}

int get_lca(int v, int u) {
  int l = min(tin[u], tin[v]);
  int r = max(tin[u], tin[v]);
  int sz = lg[r - l + 1];
  return min_h(lca[sz][l], lca[sz][r - (1 << sz) + 1]);
}

int dist(int v, int u) {
  int anc = get_lca(v, u);
  return height[v] + height[u] - 2 * height[anc];
}

void Solve() {
  cin >> n;
  tin.resize(n + 1);
  height.resize(n + 1);
  max_leaf.resize(n + 1);
  for (int i = 1, a, b; i < n; i++) {
    cin >> a >> b;
    gr[a].push_back(b);
    gr[b].push_back(a);
    if (gr[a].size() > 1)
      st = a;
    if (gr[b].size() > 1)
      st = b;
  }
  if (st == -1) {
    an.emplace_back(1, 2, 2);
    ans = 1;
  }
  else {
    pii m1 = {0, 0}, m2 = {0, 0};
    int v1 = -1, v2 = -1;
    height[st] = 1;
    for (int v: gr[st]) {
      pii temp = dfs(v, st);
      if (m1 < temp) {
        m2 = m1;
        m1 = temp;
        v2 = v1;
        v1 = v;
      }
      else if (m2 < temp)
        m2 = temp, v2 = v;
    }
    dfs_order(st, -1);
    preprocess();
    big_way.push(st);
    dfs2(v1, st, m1);
    while(big_sub.size()) {
      int cur = big_sub.top();
      big_sub.pop();
      if (dist(m1.second, cur) > dist(m2.second, cur))
        an.emplace_back(m1.second, cur, cur), ans += dist(m1.second, cur);
      else
        an.emplace_back(m2.second, cur, cur), ans += dist(m2.second, cur);
    }
    for (int v: gr[st])
      if (v != v1)
        dfs3(v, st);
    while(others.size()) {
      int cur = others.top();
      others.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
    while(big_way.size() > 1) {
      int cur = big_way.front();
      big_way.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
  }
  cout << ans << endl;
  for (auto [a, b, c] : an)
    cout << a << " " << b << " " << c << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  //auto start = chrono::high_resolution_clock::now();
  Solve();
  //auto end = chrono::high_resolution_clock::now();
  //cout << endl << (chrono::duration_cast<chrono::duration<double>>(end - start)).count();
  return 0;
}


#include<bits/stdc++.h>

#define endl "\n"
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;

constexpr int N = 1e5 + 5;
constexpr int M = 19;

int n, st = -1;
ll ans = 0;
vector<int> gr[N], height, leaves, order, lg, lca[M], tin;
vector<pii> max_leaf;
stack<int> big_sub, others;
vector<tuple<int, int, int>> an;
queue<int> big_way;

void dfs_order(int v, int p) {
  tin[v] = order.size();
  order.push_back(v);
  for (int u: gr[v]) {
    if (u != p) {
      dfs_order(u, v);
      order.push_back(v);
    }
  }
}

pii dfs(int v, int p) {
  height[v] = height[p] + 1;
  for (int u: gr[v]) {
    if (u != p)
      max_leaf[v] = max(max_leaf[v], dfs(u, v));
  }
  if (max_leaf[v] == (pii){0, 0})
    max_leaf[v] = {height[v], v};
  return max_leaf[v];
}

void dfs2(int v, int p, pii m) {
  if (max_leaf[v] != m)
    big_sub.push(v);
  else
    big_way.push(v);
  for (int u : gr[v])
    if (u != p)
      dfs2(u, v, m);
}

void dfs3(int v, int p) {
  others.push(v);
  for (int u : gr[v])
    if (u != p)
      dfs3(u, v);
}

int min_h(int v, int u) {
  return height[v] < height[u] ? v : u;
}

void preprocess() {
  int s = order.size();
  lg.resize(s + 1);
  for (int i = 2; i <= s; i++)
    lg[i] = lg[i >> 1] + 1;
  for (int i = 0; i < M; i++)
    lca[i].resize(s);
  for (int i = 0; i < s; i++)
    lca[0][i] = order[i];
  for (int i = 1; i < M; i++) {
    for (int j = 0; j + (1 << (i - 1)) < s; j++)
      lca[i][j] = min_h(lca[i - 1][j], lca[i - 1][j + (1 << (i - 1))]);
  }
}

int get_lca(int v, int u) {
  int l = min(tin[u], tin[v]);
  int r = max(tin[u], tin[v]);
  int sz = lg[r - l + 1];
  return min_h(lca[sz][l], lca[sz][r - (1 << sz) + 1]);
}

int dist(int v, int u) {
  int anc = get_lca(v, u);
  return height[v] + height[u] - 2 * height[anc];
}

void Solve() {
  cin >> n;
  tin.resize(n + 1);
  height.resize(n + 1);
  max_leaf.resize(n + 1);
  for (int i = 1, a, b; i < n; i++) {
    cin >> a >> b;
    gr[a].push_back(b);
    gr[b].push_back(a);
    if (gr[a].size() > 1)
      st = a;
    if (gr[b].size() > 1)
      st = b;
  }
  if (st == -1) {
    an.emplace_back(1, 2, 2);
    ans = 1;
  }
  else {
    pii m1 = {0, 0}, m2 = {0, 0};
    int v1 = -1, v2 = -1;
    height[st] = 1;
    for (int v: gr[st]) {
      pii temp = dfs(v, st);
      if (m1 < temp) {
        m2 = m1;
        m1 = temp;
        v2 = v1;
        v1 = v;
      }
      else if (m2 < temp)
        m2 = temp, v2 = v;
    }
    dfs_order(st, -1);
    preprocess();
    big_way.push(st);
    dfs2(v1, st, m1);
    while(big_sub.size()) {
      int cur = big_sub.top();
      big_sub.pop();
      if (dist(m1.second, cur) > dist(m2.second, cur))
        an.emplace_back(m1.second, cur, cur), ans += dist(m1.second, cur);
      else
        an.emplace_back(m2.second, cur, cur), ans += dist(m2.second, cur);
    }
    for (int v: gr[st])
      if (v != v1)
        dfs3(v, st);
    while(others.size()) {
      int cur = others.top();
      others.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
    while(big_way.size() > 1) {
      int cur = big_way.front();
      big_way.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
  }
  cout << ans << endl;
  for (auto [a, b, c] : an)
    cout << a << " " << b << " " << c << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  //auto start = chrono::high_resolution_clock::now();
  Solve();
  //auto end = chrono::high_resolution_clock::now();
  //cout << endl << (chrono::duration_cast<chrono::duration<double>>(end - start)).count();
  return 0;
}


#include<bits/stdc++.h>

#define endl "\n"
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;

constexpr int N = 2e5 + 5;
constexpr int M = 20;

int n, st = -1;
ll ans = 0;
vector<int> gr[N], height, order, lg, lca[M], tin;
vector<pii> max_leaf;
stack<int> big_sub, others;
vector<tuple<int, int, int>> an;
queue<int> big_way;

void dfs_order(int v, int p) {
  tin[v] = order.size();
  order.push_back(v);
  for (int u: gr[v]) {
    if (u != p) {
      dfs_order(u, v);
      order.push_back(v);
    }
  }
}

pii dfs(int v, int p) {
  height[v] = height[p] + 1;
  for (int u: gr[v]) {
    if (u != p)
      max_leaf[v] = max(max_leaf[v], dfs(u, v));
  }
  if (gr[v].size() == 1)
    max_leaf[v] = {height[v], v};
  return max_leaf[v];
}

void dfs2(int v, int p, pii m) {
  if (max_leaf[v] != m)
    big_sub.push(v);
  else
    big_way.push(v);
  for (int u : gr[v])
    if (u != p)
      dfs2(u, v, m);
}

void dfs3(int v, int p) {
  others.push(v);
  for (int u : gr[v])
    if (u != p)
      dfs3(u, v);
}

int min_h(int v, int u) {
  return height[v] < height[u] ? v : u;
}

void preprocess() {
  int s = order.size();
  lg.resize(s + 1);
  for (int i = 2; i <= s; i++)
    lg[i] = lg[i >> 1] + 1;
  for (int i = 0; i < M; i++)
    lca[i].resize(s);
  for (int i = 0; i < s; i++)
    lca[0][i] = order[i];
  for (int i = 1; i < M; i++) {
    for (int j = 0; j + (1 << (i - 1)) < s; j++)
      lca[i][j] = min_h(lca[i - 1][j], lca[i - 1][j + (1 << (i - 1))]);
  }
}

int get_lca(int v, int u) {
  int l = min(tin[u], tin[v]);
  int r = max(tin[u], tin[v]);
  int sz = lg[r - l + 1];
  return min_h(lca[sz][l], lca[sz][r - (1 << sz) + 1]);
}

int dist(int v, int u) {
  int anc = get_lca(v, u);
  return height[v] + height[u] - 2 * height[anc];
}

void Solve() {
  cin >> n;
  tin.resize(n + 1);
  height.resize(n + 1);
  max_leaf.resize(n + 1);
  for (int i = 1, a, b; i < n; i++) {
    cin >> a >> b;
    gr[a].push_back(b);
    gr[b].push_back(a);
    if (gr[a].size() > 1)
      st = a;
    if (gr[b].size() > 1)
      st = b;
  }
  if (st == -1) {
    an.emplace_back(1, 2, 2);
    ans = 1;
  }
  else {
    pii m1 = {0, 0}, m2 = {0, 0};
    int v1 = -1, v2 = -1;
    for (int v: gr[st]) {
      pii temp = dfs(v, st);
      if (m1 < temp) {
        m2 = m1;
        m1 = temp;
        v2 = v1;
        v1 = v;
      }
      else if (m2 < temp)
        m2 = temp, v2 = v;
    }
    dfs_order(st, -1);
    preprocess();
    big_way.push(st);
    dfs2(v1, st, m1);
    while(big_sub.size()) {
      int cur = big_sub.top();
      big_sub.pop();
      if (dist(m1.second, cur) > dist(m2.second, cur))
        an.emplace_back(m1.second, cur, cur), ans += dist(m1.second, cur);
      else
        an.emplace_back(m2.second, cur, cur), ans += dist(m2.second, cur);
    }
    for (int v: gr[st])
      if (v != v1)
        dfs3(v, st);
    while(others.size()) {
      int cur = others.top();
      others.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
    while(big_way.size() > 1) {
      int cur = big_way.front();
      big_way.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
  }
  cout << ans << endl;
  for (auto [a, b, c] : an)
    cout << a << " " << b << " " << c << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  //auto start = chrono::high_resolution_clock::now();
  Solve();
  //auto end = chrono::high_resolution_clock::now();
  //cout << endl << (chrono::duration_cast<chrono::duration<double>>(end - start)).count();
  return 0;
}


#include<bits/stdc++.h>

#define endl "\n"
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;

constexpr int N = 1e5 + 5;
constexpr int M = 19;

int n, st = -1;
ll ans = 0;
vector<int> gr[N], height, leaves, order, lg, lca[M], tin;
vector<pii> max_leaf;
stack<int> big_sub, others;
vector<tuple<int, int, int>> an;
queue<int> big_way;

void dfs_order(int v, int p) {
  tin[v] = order.size();
  order.push_back(v);
  for (int u: gr[v]) {
    if (u != p) {
      dfs_order(u, v);
      order.push_back(v);
    }
  }
}

pii dfs(int v, int p) {
  height[v] = height[p] + 1;
  for (int u: gr[v]) {
    if (u != p)
      max_leaf[v] = max(max_leaf[v], dfs(u, v));
  }
  if (max_leaf[v] == (pii){0, 0})
    max_leaf[v] = {height[v], v};
  return max_leaf[v];
}

void dfs2(int v, int p, pii m) {
  if (max_leaf[v] != m)
    big_sub.push(v);
  else
    big_way.push(v);
  for (int u : gr[v])
    if (u != p)
      dfs2(u, v, m);
}

void dfs3(int v, int p) {
  others.push(v);
  for (int u : gr[v])
    if (u != p)
      dfs3(u, v);
}

int min_h(int v, int u) {
  return height[v] < height[u] ? v : u;
}

void preprocess() {
  int n = order.size();
  lg.resize(n + 1);
  for (int i = 2; i <= n; i++)
    lg[i] = lg[i >> 1] + 1;
  for (int i = 0; i < M; i++)
    lca[i].resize(n);
  for (int i = 0; i < n; i++)
    lca[0][i] = order[i];
  for (int i = 1; i < M; i++) {
    for (int j = 0; j + (1 << (i - 1)) < n; j++)
      lca[i][j] = min_h(lca[i - 1][j], lca[i - 1][j + (1 << (i - 1))]);
  }
}

int get_lca(int v, int u) {
  int l = min(tin[u], tin[v]);
  int r = max(tin[u],tin[v]);
  int sz = lg[r - l + 1];
  return min_h(lca[sz][l], lca[sz][r - (1 << sz) + 1]);
}

int dist(int v, int u) {
  int anc = get_lca(v, u);
  return height[v] + height[u] - 2 * height[anc];
}

void Solve() {
  cin >> n;
  tin.resize(n + 1);
  height.resize(n + 1);
  max_leaf.resize(n + 1);
  for (int i = 1, a, b; i < n; i++) {
    cin >> a >> b;
    gr[a].push_back(b);
    gr[b].push_back(a);
    if (gr[a].size() > 1)
      st = a;
    if (gr[b].size() > 1)
      st = b;
  }
  if (st == -1) {
    an.emplace_back(1, 2, 2);
    ans = 1;
  }
  else {
    pii m1 = {0, 0}, m2 = {0, 0};
    int v1 = -1, v2 = -1;
    height[st] = 1;
    for (int v: gr[st]) {
      pii temp = dfs(v, st);
      if (m1 < temp) {
        m2 = m1;
        m1 = temp;
        v2 = v1;
        v1 = v;
      }
      else if (m2 < temp)
        m2 = temp, v2 = v;
    }
    dfs_order(st, -1);
    preprocess();
    big_way.push(st);
    dfs2(v1, st, m1);
    while(big_sub.size()) {
      int cur = big_sub.top();
      big_sub.pop();
      if (dist(m1.second, cur) > dist(m2.second, cur))
        an.emplace_back(m1.second, cur, cur), ans += dist(m1.second, cur);
      else
        an.emplace_back(m2.second, cur, cur), ans += dist(m2.second, cur);
    }
    for (int v: gr[st])
      if (v != v1)
        dfs3(v, st);
    while(others.size()) {
      int cur = others.top();
      others.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
    while(big_way.size() > 1) {
      int cur = big_way.front();
      big_way.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
  }
  cout << ans << endl;
  for (auto [a, b, c] : an)
    cout << a << " " << b << " " << c << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  //auto start = chrono::high_resolution_clock::now();
  Solve();
  //auto end = chrono::high_resolution_clock::now();
  //cout << endl << (chrono::duration_cast<chrono::duration<double>>(end - start)).count();
  return 0;
}


#include<bits/stdc++.h>

#define endl "\n"
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;

constexpr int N = 2e5 + 5;
constexpr int M = 20;

int n, st = -1;
ll ans = 0;
vector<int> gr[N], height, order, lg, lca[M], tin;
vector<pii> max_leaf;
stack<int> others;
vector<tuple<int, int, int>> an;
queue<int> big_way;

void dfs_order(int v, int p) {
  tin[v] = order.size();
  order.push_back(v);
  for (int u: gr[v]) {
    if (u != p) {
      dfs_order(u, v);
      order.push_back(v);
    }
  }
}

pii dfs(int v, int p) {
  height[v] = height[p] + 1;
  for (int u: gr[v]) {
    if (u != p)
      max_leaf[v] = max(max_leaf[v], dfs(u, v));
  }
  if (gr[v].size() == 1)
    max_leaf[v] = {height[v], v};
  return max_leaf[v];
}

void dfs2(int v, int p, pii m1, pii m2) {
  if (max_leaf[v] != m1 && max_leaf[v] != m2)
    others.push(v);
  else
    big_way.push(v);
  for (int u : gr[v])
    if (u != p)
      dfs2(u, v, m1, m2);
}

int min_h(int v, int u) {
  return height[v] < height[u] ? v : u;
}

void preprocess() {
  int s = order.size();
  lg.resize(s + 1);
  for (int i = 2; i <= s; i++)
    lg[i] = lg[i >> 1] + 1;
  for (int i = 0; i < M; i++)
    lca[i].resize(s);
  for (int i = 0; i < s; i++)
    lca[0][i] = order[i];
  for (int i = 1; i < M; i++) {
    for (int j = 0; j + (1 << (i - 1)) < s; j++)
      lca[i][j] = min_h(lca[i - 1][j], lca[i - 1][j + (1 << (i - 1))]);
  }
}

int get_lca(int v, int u) {
  int l = min(tin[u], tin[v]);
  int r = max(tin[u], tin[v]);
  int sz = lg[r - l + 1];
  return min_h(lca[sz][l], lca[sz][r - (1 << sz) + 1]);
}

int dist(int v, int u) {
  int anc = get_lca(v, u);
  return height[v] + height[u] - 2 * height[anc];
}

void Solve() {
  cin >> n;
  tin.resize(n + 1);
  height.resize(n + 1);
  max_leaf.resize(n + 1);
  for (int i = 1, a, b; i < n; i++) {
    cin >> a >> b;
    gr[a].push_back(b);
    gr[b].push_back(a);
    if (gr[a].size() > 1)
      st = a;
    if (gr[b].size() > 1)
      st = b;
  }
  if (st == -1) {
    an.emplace_back(1, 2, 2);
    ans = 1;
  }
  else {
    pii m1 = {0, 0}, m2 = {0, 0};
    int v1 = -1, v2 = -1;
    for (int v: gr[st]) {
      pii temp = dfs(v, st);
      if (m1 < temp) {
        m2 = m1;
        m1 = temp;
        v2 = v1;
        v1 = v;
      }
      else if (m2 < temp)
        m2 = temp, v2 = v;
    }
    max_leaf[st] = m1;
    dfs_order(st, -1);
    preprocess();
    dfs2(st, -1, m1, m2);
    while(others.size()) {
      int cur = others.top();
      others.pop();
      if (dist(m1.second, cur) > dist(m2.second, cur))
        an.emplace_back(m1.second, cur, cur), ans += dist(m1.second, cur);
      else
        an.emplace_back(m2.second, cur, cur), ans += dist(m2.second, cur);
    }
    while(big_way.size() > 1) {
      int cur = big_way.front();
      if (cur == m1.second)
        swap(m1.second, m2.second);
      big_way.pop();
      ans += dist(m1.second, cur);
      an.emplace_back(m1.second, cur, cur);
    }
  }
  cout << ans << endl;
  for (auto [a, b, c] : an)
    cout << a << " " << b << " " << c << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  //auto start = chrono::high_resolution_clock::now();
  Solve();
  //auto end = chrono::high_resolution_clock::now();
  //cout << endl << (chrono::duration_cast<chrono::duration<double>>(end - start)).count();
  return 0;
}


#include<bits/stdc++.h>

#define endl "\n"
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;

constexpr int N = 2e5 + 5;
constexpr int M = 20;

int n, st = -1;
ll ans = 0;
vector<int> gr[N], height, order, lg, lca[M], tin, sz;
vector<pii> diam;
stack<int> others;
vector<tuple<int, int, int>> an;
queue<int> part_1, part_2;

void dfs_order(int v, int p) {
  tin[v] = order.size();
  order.push_back(v);
  for (int u: gr[v]) {
    if (u != p) {
      dfs_order(u, v);
      order.push_back(v);
    }
  }
}

auto comp = [&](const int& a, const int& b) {
  return sz[a] > sz[b];
};

int dfs1(int v, int p = -1) {
  int s = 1;
  sz[v] = 0;
  for (int u: gr[v])
    if (u != p)
      s += dfs1(u, v);
  sort(gr[v].begin(), gr[v].end(), comp);
  return sz[v] = s;
}

int find_centroid(int v = 1) {
  dfs1(v);
  int u = v;
  while(sz[gr[u].front()] > sz[v] / 2)
    u = gr[u].front();
  return u;
}

void upd(pii&a, pii b) {
  auto& [a1, a2] = a;
  auto [b1, b2] = b;
  if (height[a1] < height[b1]) {
    a2 = a1;
    a1 = b1;
    if (height[a2] < height[b2])
      a2 = b2;
  }
  else if (height[a2] < height[b1])
    a2 = b1;
}

pii dfs(int v, int p) {
  height[v] = height[p] + 1;
  for (int u: gr[v]) {
    if (u != p)
      upd(diam[v], dfs(u, v));
  }
  if (gr[v].size() == 1)
    diam[v] = {v, 0};
  return diam[v];
}

void dfs2(int v, int p, pii m) {
  if (diam[v].first != m.first && diam[v].first != m.second)
    others.push(v);
  if (diam[v].first == m.first)
    part_1.push(v);
  for (int u : gr[v])
    if (u != p)
      dfs2(u, v, m);
  if (diam[v].first == m.second)
    part_2.push(v);
}

int min_h(int v, int u) {
  return height[v] < height[u] ? v : u;
}

void preprocess() {
  int s = order.size();
  lg.resize(s + 1);
  for (int i = 2; i <= s; i++)
    lg[i] = lg[i >> 1] + 1;
  for (int i = 0; i < M; i++)
    lca[i].resize(s);
  for (int i = 0; i < s; i++)
    lca[0][i] = order[i];
  for (int i = 1; i < M; i++) {
    for (int j = 0; j + (1 << (i - 1)) < s; j++)
      lca[i][j] = min_h(lca[i - 1][j], lca[i - 1][j + (1 << (i - 1))]);
  }
}

int get_lca(int v, int u) {
  int l = min(tin[u], tin[v]);
  int r = max(tin[u], tin[v]);
  int sz = lg[r - l + 1];
  return min_h(lca[sz][l], lca[sz][r - (1 << sz) + 1]);
}

int dist(int v, int u) {
  int anc = get_lca(v, u);
  return height[v] + height[u] - 2 * height[anc];
}

void Solve() {
  cin >> n;
  tin.resize(n + 1);
  height.resize(n + 1);
  diam.resize(n + 1);
  sz.resize(n + 1);
  for (int i = 1, a, b; i < n; i++) {
    cin >> a >> b;
    gr[a].push_back(b);
    gr[b].push_back(a);
  }
  height[0] = 0;
  st = find_centroid();
  pii m = dfs(st, 0);
  dfs_order(st, -1);
  preprocess();
  dfs2(st, -1, m);
  while(others.size()) {
    int cur = others.top();
    others.pop();
    if (dist(m.second, cur) > dist(m.first, cur))
      an.emplace_back(m.second, cur, cur), ans += dist(m.second, cur);
    else
      an.emplace_back(m.first, cur, cur), ans += dist(m.first, cur);
  }
  while(part_2.size()) {
    int cur = part_2.front();
    part_2.pop();
    ans += dist(m.first, cur);
    an.emplace_back(m.first, cur, cur);
  }
  while(part_1.size() > 1) {
    int cur = part_1.front();
    part_1.pop();
    ans += dist(m.first, cur);
    an.emplace_back(m.first, cur, cur);
  }
  cout << ans << endl;
  for (auto [a, b, c] : an)
    cout << a << " " << b << " " << c << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  //auto start = chrono::high_resolution_clock::now();
  Solve();
  //auto end = chrono::high_resolution_clock::now();
  //cout << endl << (chrono::duration_cast<chrono::duration<double>>(end - start)).count();
  return 0;
}