#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
#include <ctime>
typedef  long long ll;
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define inf9 (1000000000)
#define MOD 1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
#define readmp(n) for(int i=0,u,v;i<n;i++) {scanf("%d%d",&u,&v); mp[u].push_back(v); mp[v].push_back(u);}
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef ll ValType;
template<typename  T> void maxtt(T& t1, T t2) {
    t1=max(t1,t2);
}
template<typename  T> void mintt(T& t1, T t2) {
    t1=min(t1,t2);
}
#define MAX 105

bool debug = 0;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
string direc="RDLU";
ll ln, lk, lm;
void etp(bool f = 0) {
    puts(f ?"YES" : "NO");
    exit(0);
}
void addmod(int &x, int y, int mod = MOD) {
    assert(y>=0);
    x+=y; if (x>=mod) x-=mod;
    assert(x>=0 && x<mod);
}
void et(int x=-1) {
    printf("%d\n", x); exit(0);
}
ll fastPow(ll x, ll y, ll mod=MOD) {
    ll ans = 1;
    while(y>0) {
        if(y&1) ans = (x * ans)%mod;
        x = x*x%mod;
        y>>=1;
    }
    return ans;
}
ll gcd1(ll x, ll y) { return y?gcd1(y,x%y):x;}

bool rd(ll l, ll r) {
    cout<<l<<" "<<r<<endl;
    string x; cin>>x;
    if(x[0]=='Y') {
        if(l==r) exit(0);
        return 1;
    }
    if (x[0]=='B') exit(0);
    return 0;
}
void fmain(int ID) {
    cin>>ln>>k;
    ll l=1,r=ln;
    REP(i,5000){
        if (r-l+1<=50) {
            int len=r-l+1;
            mt19937 mt_rand((int)time(0));
            int x= (mt_rand()%len+len)%len;

            int tar = l+x;
            rd(tar, tar);

            l=max(1LL,l-k);
            r=min(ln, r+k);
            continue;
        }
        ll mid=(l+r)/2;
        bool fg = rd(l, mid);
        if (fg) {
            r=mid;
        } else l=mid+1;
        l=max(1LL,l-k);
        r=min(ln, r+k);
    }
}

int main() {
    int t=1;
//    scanf("%d", &t);
    REQ(i,t) {
        fmain(i);
    }
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
#include <ctime>
typedef  long long ll;
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define inf9 (1000000000)
#define MOD 1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
#define readmp(n) for(int i=0,u,v;i<n;i++) {scanf("%d%d",&u,&v); mp[u].push_back(v); mp[v].push_back(u);}
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef ll ValType;
template<typename  T> void maxtt(T& t1, T t2) {
    t1=max(t1,t2);
}
template<typename  T> void mintt(T& t1, T t2) {
    t1=min(t1,t2);
}
#define MAX 105

bool debug = 0;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
string direc="RDLU";
ll ln, lk, lm;
void etp(bool f = 0) {
    puts(f ?"YES" : "NO");
    exit(0);
}
void addmod(int &x, int y, int mod = MOD) {
    assert(y>=0);
    x+=y; if (x>=mod) x-=mod;
    assert(x>=0 && x<mod);
}
void et(int x=-1) {
    printf("%d\n", x); exit(0);
}
ll fastPow(ll x, ll y, ll mod=MOD) {
    ll ans = 1;
    while(y>0) {
        if(y&1) ans = (x * ans)%mod;
        x = x*x%mod;
        y>>=1;
    }
    return ans;
}
ll gcd1(ll x, ll y) { return y?gcd1(y,x%y):x;}

bool rd(ll l, ll r) {
    cout<<l<<" "<<r<<endl;
    string x; cin>>x;
    if(x[0]=='Y') {
        if(l==r) exit(0);
        return 1;
    }
    if (x[0]=='B') exit(0);
    return 0;
}
void fmain(int ID) {
    cin>>ln>>k;
    ll l=1,r=ln;
    mt19937 mt_rand((int)time(0));

    REP(i,4500){
        if (r-l+1<=k*4) {
            int len=r-l+1;

            int x= (mt_rand()%len+len)%len;

            int tar = l+x;
            rd(tar, tar);

            l=max(1LL,l-k);
            r=min(ln, r+k);
            continue;
        }
        ll mid=(l+r)/2;
        bool fg = rd(l, mid);
        if (fg) {
            r=mid;
        } else l=mid+1;
        l=max(1LL,l-k);
        r=min(ln, r+k);
    }
}

int main() {
    int t=1;
//    scanf("%d", &t);
    REQ(i,t) {
        fmain(i);
    }
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
#include <ctime>
typedef  long long ll;
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define inf9 (1000000000)
#define MOD 1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
#define readmp(n) for(int i=0,u,v;i<n;i++) {scanf("%d%d",&u,&v); mp[u].push_back(v); mp[v].push_back(u);}
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef ll ValType;
template<typename  T> void maxtt(T& t1, T t2) {
    t1=max(t1,t2);
}
template<typename  T> void mintt(T& t1, T t2) {
    t1=min(t1,t2);
}
#define MAX 105

bool debug = 0;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
string direc="RDLU";
ll ln, lk, lm;
void etp(bool f = 0) {
    puts(f ?"YES" : "NO");
    exit(0);
}
void addmod(int &x, int y, int mod = MOD) {
    assert(y>=0);
    x+=y; if (x>=mod) x-=mod;
    assert(x>=0 && x<mod);
}
void et(int x=-1) {
    printf("%d\n", x); exit(0);
}
ll fastPow(ll x, ll y, ll mod=MOD) {
    ll ans = 1;
    while(y>0) {
        if(y&1) ans = (x * ans)%mod;
        x = x*x%mod;
        y>>=1;
    }
    return ans;
}
ll gcd1(ll x, ll y) { return y?gcd1(y,x%y):x;}

bool rd(ll l, ll r) {
    cout<<l<<" "<<r<<endl;
    string x; cin>>x;
    if(x[0]=='Y') {
        if(l==r) exit(0);
        return 1;
    }
    if (x[0]=='B') exit(0);
    return 0;
}
void fmain(int ID) {
    cin>>ln>>k;
    ll l=1,r=ln;
    while (1) {
        if (r-l+1<=k*4+5) {
            int len=r-l+1;
            int x = (rand() * 10000 + rand()) % len;
            int tar = l+x;
            rd(tar, tar);

            l=max(1LL,l-k);
            r=min(ln, r+k);
            continue;
        }
        ll mid=(l+r)/2;
        bool fg = rd(l, mid);
        if (fg) {
            r=mid;
        } else l=mid+1;
        l=max(1LL,l-k);
        r=min(ln, r+k);
    }
}

int main() {
    int t=1;
//    scanf("%d", &t);
    REQ(i,t) {
        fmain(i);
    }
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#define MAXN 200001
#define ll long long
using namespace std;
typedef struct node{
	ll deep,point;
	node(){
		deep=0;point=0;
	}
	node(ll a,ll b){
		point=a;deep=b;
	}
}NODE;
typedef struct answer{
	ll src,dst,del;
	answer(ll a,ll b,ll c){
		src=a;dst=b;del=c;
	}
}ANS;
ll n,ans,d1,d2,vis[MAXN];
NODE sp[MAXN];
vector<ll> map[MAXN];
ll read(){
	ll ans=0;
	char x=getchar();
	while(x>'9'||x<'0')x=getchar();
	while(x<='9'&&x>='0'){
		ans=ans*10+x-'0';
		x=getchar();
	}
	return ans;
}
ll bfs(ll rt){
	ll ret=rt;
	queue<NODE*> q;
	memset(vis,0,sizeof(vis));
	q.push(new NODE(rt,0));
	vis[rt]=1;
	while(!q.empty()){
		NODE *np=q.front();
		if(sp[np->point].deep<np->deep&&(rt==d1||rt==d2)){
			sp[np->point].deep=np->deep;
			sp[np->point].point=rt;
		}
		if(sp[np->point].deep>=sp[ret].deep){
			ret=np->point;
		}
		for(int i=1;i<map[np->point].size();i++){
			if(!vis[map[np->point][i]]){
				q.push(new NODE(map[np->point][i],np->deep+1));
				vis[map[np->point][i]]=1;
			}
		}
		q.pop();
	}
	return ret;
}
int main(){
	ll rt;
	queue<ll> sq;
	queue<ANS*> slove;
	n=read();
	for(ll i=1;i<=n;i++)map[i].push_back(0);
	for(ll i=1,a,b;i<n;i++){
		a=read(),b=read();
		map[a].push_back(b);
		map[b].push_back(a);
		map[a][0]++;map[b][0]++;
	}
	for(int i=1;i<=n;i++){
		if(map[i][0]==1){
			rt=i;break;
		}
	}
	d1=bfs(rt);
	d2=bfs(d1);
	bfs(d2);
	memset(vis,0,sizeof(vis));
	for(int i=1;i<=n;i++){
		if(map[i][0]==1&&i!=d1&&i!=d2){
			sq.push(i);
			vis[i]=1;
		}
	}
	while(!sq.empty()){
		ll tmp=sq.front();
		ans+=sp[tmp].deep;
		slove.push(new ANS(tmp,sp[tmp].point,tmp));
		//cout<<tmp<<" "<<sp[tmp].point<<" "<<tmp<<endl;
		vis[tmp]=1;
		for(int i=1;i<map[tmp].size();i++){
			if(!vis[map[tmp][i]])map[map[tmp][i]][0]--;
			if(!vis[map[tmp][i]]&&map[map[tmp][i]][0]==1){
				sq.push(map[tmp][i]);
			}
		}
		sq.pop();
	}
	//cout<<d1<<" "<<d2<<endl;
	vis[d1]=1;
	for(int i=sp[d1].deep,src=d1;i>0;i--){
		ans+=i;
		for(int j=1;j<map[src].size();j++){
			if(!vis[map[src][j]]){
				vis[map[src][j]]=1;
				slove.push(new ANS(src,d2,src));
				//cout<<src<<" "<<map[src][j]<<" "<<src<<endl;
				src=map[src][j];
				break;
			}
		}
	}
	cout<<ans<<endl;
	while(!slove.empty()){
		ANS *atmp=slove.front();
		cout<<atmp->src<<" "<<atmp->dst<<" "<<atmp->del<<endl;
		slove.pop();
	}
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#define MAXN 200001
#define ll long long
using namespace std;
typedef struct node{
	ll deep,point;
	node(){
		deep=0;point=0;
	}
	node(ll a,ll b){
		point=a;deep=b;
	}
}NODE;
typedef struct answer{
	ll src,dst,del;
	answer(ll a,ll b,ll c){
		src=a;dst=b;del=c;
	}
}ANS;
ll n,ans,d1,d2,vis[MAXN];
NODE sp[MAXN];
vector<ll> map[MAXN];
ll read(){
	ll ans=0;
	char x=getchar();
	while(x>'9'||x<'0')x=getchar();
	while(x<='9'&&x>='0'){
		ans=ans*10+x-'0';
		x=getchar();
	}
	return ans;
}
ll bfs(ll rt){
	ll ret=rt;
	queue<NODE*> q;
	memset(vis,0,sizeof(vis));
	q.push(new NODE(rt,0));
	vis[rt]=1;
	while(!q.empty()){
		NODE *np=q.front();
		if(sp[np->point].deep<np->deep){
			sp[np->point].deep=np->deep;
			sp[np->point].point=rt;
		}
		if(sp[np->point].deep>=sp[ret].deep){
			ret=np->point;
		}
		//cout<<map[np->point].size()<<endl;
		for(int i=1;i<map[np->point].size();i++){
			//cout<<map[np->point][i]<<" "<<np->deep+1<<endl;
			if(!vis[map[np->point][i]]){
				//cout<<map[np->point][i]<<" "<<np->deep+1<<endl;
				q.push(new NODE(map[np->point][i],np->deep+1));
				vis[map[np->point][i]]=1;
			}
		}
		q.pop();
	}
	return ret;
}
int main(){
	ll rt;
	queue<ll> sq;
	queue<ANS*> slove;
	n=read();
	for(ll i=1;i<=n;i++)map[i].push_back(0);
	for(ll i=1,a,b;i<n;i++){
		a=read(),b=read();
		map[a].push_back(b);
		map[b].push_back(a);
		map[a][0]++;map[b][0]++;
	}
	for(int i=1;i<=n;i++){
		if(map[i][0]==1){
			rt=i;break;
		}
	}
	d1=bfs(rt);
	d2=bfs(d1);
	bfs(d2);
	memset(vis,0,sizeof(vis));
	for(int i=1;i<=n;i++){
		if(map[i][0]==1&&i!=d1&&i!=d2){
			sq.push(i);
			vis[i]=1;
		}
	}
	while(!sq.empty()){
		ll tmp=sq.front();
		ans+=sp[tmp].deep;
		slove.push(new ANS(tmp,sp[tmp].point,tmp));
		//cout<<tmp<<" "<<sp[tmp].point<<" "<<tmp<<endl;
		vis[tmp]=1;
		for(int i=1;i<map[tmp].size();i++){
			if(!vis[map[tmp][i]])map[map[tmp][i]][0]--;
			if(!vis[map[tmp][i]]&&map[map[tmp][i]][0]==1){
				sq.push(map[tmp][i]);
			}
		}
		sq.pop();
	}
	for(int i=sp[d1].deep,src=d1;i>0;i--){
		ans+=i;
		for(int j=1;j<map[src].size();j++){
			if(!vis[map[src][j]]){
				vis[map[src][j]]=1;
				slove.push(new ANS(src,d2,src));
				//cout<<src<<" "<<map[src][j]<<" "<<src<<endl;
				src=map[src][j];
				break;
			}
		}
	}
	cout<<ans<<endl;
	while(!slove.empty()){
		ANS *atmp=slove.front();
		cout<<atmp->src<<" "<<atmp->dst<<" "<<atmp->del<<endl;
		slove.pop();
	}
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#define MAXN 200001
#define ll long long
using namespace std;
typedef struct node{
	ll deep,point;
	node(){
		deep=0;point=0;
	}
	node(ll a,ll b){
		point=a;deep=b;
	}
}NODE;
typedef struct answer{
	ll src,dst,del;
	answer(ll a,ll b,ll c){
		src=a;dst=b;del=c;
	}
}ANS;
ll n,ans,d1,d2,vis[MAXN];
NODE sp[MAXN];
vector<ll> map[MAXN];
ll read(){
	ll ans=0;
	char x=getchar();
	while(x>'9'||x<'0')x=getchar();
	while(x<='9'&&x>='0'){
		ans=ans*10+x-'0';
		x=getchar();
	}
	return ans;
}
ll bfs(ll rt){
	ll ret=rt;
	queue<NODE*> q;
	memset(vis,0,sizeof(vis));
	q.push(new NODE(rt,0));
	vis[rt]=1;
	while(!q.empty()){
		NODE *np=q.front();
		if(sp[np->point].deep<np->deep){
			sp[np->point].deep=np->deep;
			sp[np->point].point=rt;
		}
		if(sp[np->point].deep>=sp[ret].deep){
			ret=np->point;
		}
		//cout<<map[np->point].size()<<endl;
		for(int i=1;i<map[np->point].size();i++){
			//cout<<map[np->point][i]<<" "<<np->deep+1<<endl;
			if(!vis[map[np->point][i]]){
				//cout<<map[np->point][i]<<" "<<np->deep+1<<endl;
				q.push(new NODE(map[np->point][i],np->deep+1));
				vis[map[np->point][i]]=1;
			}
		}
		q.pop();
	}
	return ret;
}
int main(){
	ll rt;
	queue<ll> sq;
	queue<ANS*> slove;
	n=read();
	for(ll i=1;i<=n;i++)map[i].push_back(0);
	for(ll i=1,a,b;i<n;i++){
		a=read(),b=read();
		map[a].push_back(b);
		map[b].push_back(a);
		map[a][0]++;map[b][0]++;
	}
	for(int i=1;i<=n;i++){
		if(map[i][0]==1){
			rt=i;break;
		}
	}
	d1=bfs(rt);
	d2=bfs(d1);
	bfs(d2);
	memset(vis,0,sizeof(vis));
	for(int i=1;i<=n;i++){
		if(map[i][0]==1&&i!=d1&&i!=d2){
			sq.push(i);
			vis[i]=1;
		}
	}
	while(!sq.empty()){
		ll tmp=sq.front();
		ans+=sp[tmp].deep;
		slove.push(new ANS(tmp,sp[tmp].point,tmp));
		//cout<<tmp<<" "<<sp[tmp].point<<" "<<tmp<<endl;
		vis[tmp]=1;
		for(int i=1;i<map[tmp].size();i++){
			if(!vis[map[tmp][i]])map[map[tmp][i]][0]--;
			if(!vis[map[tmp][i]]&&map[map[tmp][i]][0]==1){
				sq.push(map[tmp][i]);
			}
		}
		sq.pop();
	}
	for(int i=sp[d1].deep,src=d1;i>0;i--){
		ans+=i;
		for(int j=1;j<map[src].size();j++){
			if(!vis[map[src][j]]){
				vis[map[src][j]]=1;
				slove.push(new ANS(src,map[src][j],src));
				//cout<<src<<" "<<map[src][j]<<" "<<src<<endl;
				src=map[src][j];
				break;
			}
		}
	}
	cout<<ans<<endl;
	while(!slove.empty()){
		ANS *atmp=slove.front();
		cout<<atmp->src<<" "<<atmp->dst<<" "<<atmp->del<<endl;
		slove.pop();
	}
}


#include<bits/stdc++.h>
using namespace std;
long long a,b,c,d,e,i,j,ii,jj,zx,xc,qw[200009],we[200009],pas,pi,k[200009];
pair <pair <long long, long long>, long long> p[600009];
bool bo[200009],rko[200009];
vector <long long> v[200009];
deque <long long> de;
void dfsst(long long q, long long w, long long rr){
    if(rr>xc){
        xc=rr;
        zx=q;
    }
    for(vector <long long>::iterator it=v[q].begin(); it!=v[q].end(); it++){
        if((*it)==w) continue;
        dfsst((*it),q,rr+1);
    }
}
void dfsst2(long long q, long long w, long long rr){
    if(rr>xc){
        xc=rr;
        zx=q;
    }
    for(vector <long long>::iterator it=v[q].begin(); it!=v[q].end(); it++){
        if((*it)==w) continue;
        dfsst2((*it),q,rr+1);
    }
}
void dfs(long long q, long long w, long long rr){
    qw[q]=rr-1;
    for(vector <long long>::iterator it=v[q].begin(); it!=v[q].end(); it++){
        if((*it)==w) continue;
        dfs((*it),q,rr+1);
    }
}
void dfs2(long long q, long long w, long long rr){
    if(d==0) bo[q]=1;
    if(q==e) d=1;
    we[q]=rr-1;
    for(vector <long long>::iterator it=v[q].begin(); it!=v[q].end(); it++){
        if((*it)==w) continue;
        dfs2((*it),q,rr+1);
    }
    if(d==0) bo[q]=0;
}
void dfs3(long long q, long long w){
    if(q==zx) return;
    pi++;
    p[pi].first.first=q;
    p[pi].first.second=zx;
    p[pi].second=q;
    for(vector <long long>::iterator it=v[q].begin(); it!=v[q].end(); it++){
        if((*it)==w) continue;
        if(bo[(*it)]==1){
            dfs3((*it),q);
            return;
        }
    }
}
int main(){
    ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    cin>>a;
    for(i=1; i<a; i++){
        cin>>c>>d;
        v[c].push_back(d);
        v[d].push_back(c);
        k[c]++;k[d]++;
    }
    zx=0;xc=0;
    dfsst(1,0,1);
    e=zx;
    zx=0;xc=0;
    dfsst2(e,0,1);
    dfs(e,0,1);
    d=0;
    dfs2(zx,0,1);
    for(i=1; i<=a; i++){
        if(bo[i]==0&&v[i].size()==1){
            de.push_back(i);
            rko[i]=1;
        }
    }
    while(de.size()!=0){
        c=de.front();
        de.pop_front();
        pas+=max(qw[c],we[c]);
        pi++;
        if(qw[c]>=we[c]){
            p[pi].first.first=e;
            p[pi].first.second=c;
            p[pi].second=c;
        }else{
            p[pi].first.first=zx;
            p[pi].first.second=c;
            p[pi].second=c;
        }
        d=0;
        for(vector <long long>::iterator it=v[c].begin(); it!=v[c].end(); it++){
            if(rko[(*it)]==1) continue;
            d=(*it);break;
        }
        k[d]--;
        if(d!=0&&bo[d]==0&&k[d]==1){
            de.push_back(d);
            rko[d]=1;
        }
    }
    pas+=qw[zx]*(qw[zx]+1)/2;
    dfs3(e,0);
    cout<<pas<<endl;
    for(i=1; i<=pi; i++) cout<<p[i].first.first<<" "<<p[i].first.second<<" "<<p[i].second<<endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
long long a,b,c,d,e,i,j,ii,jj,zx,xc,qw[200009],we[200009],pas,pi;
pair <pair <long long, long long>, long long> p[600009];
bool bo[200009],rko[200009];
vector <long long> v[200009];
deque <long long> de;
void dfsst(long long q, long long w, long long rr){
    if(rr>xc){
        xc=rr;
        zx=q;
    }
    for(vector <long long>::iterator it=v[q].begin(); it!=v[q].end(); it++){
        if((*it)==w) continue;
        dfsst((*it),q,rr+1);
    }
}
void dfsst2(long long q, long long w, long long rr){
    if(rr>xc){
        xc=rr;
        zx=q;
    }
    for(vector <long long>::iterator it=v[q].begin(); it!=v[q].end(); it++){
        if((*it)==w) continue;
        dfsst2((*it),q,rr+1);
    }
}
void dfs(long long q, long long w, long long rr){
    qw[q]=rr-1;
    for(vector <long long>::iterator it=v[q].begin(); it!=v[q].end(); it++){
        if((*it)==w) continue;
        dfs((*it),q,rr+1);
    }
}
void dfs2(long long q, long long w, long long rr){
    if(d==0) bo[q]=1;
    if(q==e) d=1;
    we[q]=rr-1;
    for(vector <long long>::iterator it=v[q].begin(); it!=v[q].end(); it++){
        if((*it)==w) continue;
        dfs2((*it),q,rr+1);
    }
    if(d==0) bo[q]=0;
}
void dfs3(long long q, long long w){
    if(q==zx) return;
    pi++;
    p[pi].first.first=q;
    p[pi].first.second=zx;
    p[pi].second=q;
    for(vector <long long>::iterator it=v[q].begin(); it!=v[q].end(); it++){
        if((*it)==w) continue;
        if(bo[(*it)]==1){
            dfs3((*it),q);
            return;
        }
    }
}
int main(){
    ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    cin>>a;
    for(i=1; i<a; i++){
        cin>>c>>d;
        v[c].push_back(d);
        v[d].push_back(c);
    }
    zx=0;xc=0;
    dfsst(1,0,1);
    e=zx;
    zx=0;xc=0;
    dfsst2(e,0,1);
    dfs(e,0,1);
    d=0;
    dfs2(zx,0,1);
    for(i=1; i<=a; i++){
        if(bo[i]==0&&v[i].size()==1){
            de.push_back(i);
            rko[i]=1;
        }
    }
    while(de.size()!=0){
        c=de.front();
        de.pop_front();
        pas+=max(qw[c],we[c]);
        pi++;
        if(qw[c]>=we[c]){
            p[pi].first.first=e;
            p[pi].first.second=c;
            p[pi].second=c;
        }else{
            p[pi].first.first=zx;
            p[pi].first.second=c;
            p[pi].second=c;
        }
        d=0;
        for(vector <long long>::iterator it=v[c].begin(); it!=v[c].end(); it++){
            if(rko[(*it)]==1) continue;
            d=(*it);break;
        }
        if(d!=0&&bo[d]==0){
            de.push_back(d);
            rko[d]=1;
        }
    }
    pas+=qw[zx]*(qw[zx]+1)/2;
    dfs3(e,0);
    cout<<pas<<endl;
    for(i=1; i<=pi; i++) cout<<p[i].first.first<<" "<<p[i].first.second<<" "<<p[i].second<<endl;
    return 0;
}


#include <bits/stdc++.h>
typedef long long int ll;
typedef long double ld;
#define pb push_back
#define pii pair < int , ll >
#define F first
#define S second
#define int long long int
#define sync ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#pragma GCC optimize ("Ofast")
using namespace std;
/*
310 304 317 489 225 131 160 195 197 199 220 203 239 269
407 226 411 415 422 482 520 521 221 222 223 224*/

//const int N=2e5+100;

const int N=2e5+10,M=22;
ll par[N][M];
//ll sub[N];
ll hi[N];
vector <int> g[N];
ll dfs(ll v,ll p,ll h){
    //sub[v]=1;
    hi[v]=h;
    for (int i=0;i<g[v].size();i++){
        ll u=g[v][i];
        if (u!=p){
            par[u][0]=v;
            dfs(u,v,h+1);
           // sub[v]+=sub[u];
        }
    }
   // return sub[v];
}
ll getpar(ll v,ll h){
    if (h==-1 || h==0){
        return v;
    }
    for(int i=0;i<M;i++){
        if (h & (1 << i)) v = par[v][i];
    }
    return v;
}
int lca(int v, int u) {
    if (hi[v]<hi[u]){
        ll y=v;
        v=u;
        u=y;
    }
    v = getpar(v,hi[v]-hi[u]);
    if (v==u){
        return v;
    }
    for(int i=20;i>=0;i--){
        if (par[v][i] != par[u][i]) {
            v=par[v][i];
            u=par[u][i];
        }

    }
    return par[v][0];
}
ll ras1,ras2;
ll ma=0;
ll dfsm(ll v,ll p,ll h){
    if (h>ma){
        ma=h;
        ras1=v;
    }
    for (int i=0;i<g[v].size();i++){
        ll u=g[v][i];
        if (u!=p){
            dfsm(u,v,h+1);
        }
    }
}
ll dfsm1(ll v,ll p,ll h){
    if (h>ma){
        ma=h;
        ras2=v;
    }
    for (int i=0;i<g[v].size();i++){
        ll u=g[v][i];
        if (u!=p){
            dfsm1(u,v,h+1);
        }
    }
}
ll t[N];
ll vis[N];
int32_t main(){
    sync;
    ll n;
    cin >> n ;
    for (int i=0;i<n-1;i++){
        ll u,v;
        cin >> u >> v;
        g[u].pb(v);
        g[v].pb(u);
    }

    dfs(1,1,1);

    for (int i=1;i<M;i++){
        for (int j=1;j<=n;j++){
            par[j][i]=par[par[j][i-1]][i-1];
        }
    }
   // cout << 2 << " " << lca (2,3) << endl;
    dfsm(1,1,1);
    ma=0;
    dfsm1(ras1,ras1,1);
    vector <int> a;
 //   cout << ras1 << " " << ras2 << endl;
    for (int i=1;i<n+1;i++){
        t[i]=g[i].size();
    }

    for (int i=1;i<=n;i++){
        if (t[i]==1 && i!=ras1 && i!=ras2){
            a.pb(i);
        }
    }
    ll ans=0;
    vector <pair <pii,int> > y;
    while(a.size()){
        ll p=a.size();
        ll v=a[p-1];
        ll f1=lca(v,ras1);
        ll f2=lca(v,ras2);
        ll h1=-hi[f1]+hi[v]-hi[f1]+hi[ras1];
        ll h2=-hi[f2]+hi[v]-hi[f2]+hi[ras2];
        if (h1>h2){
            y.pb({{v,ras1},v});
            ans+=h1;
        }
        else{
            y.pb({{v,ras2},v});
            ans+=h2;
        }
        //cout << v << endl;
        vis[v]=1;
        a.pop_back();
        for (int i=0;i<g[v].size();i++){
            ll u=g[v][i];
            t[u]--;
            //cout << u << " " << t[u] << endl;
            if (vis[u]==0 && t[u]<=1){
                a.pb(u);
               // cout << u << " jnrf" << endl;

            }
        }

    }
    ll k=0;
    ll f=lca(ras1,ras2);
   // cout << ans << endl;
   // cout << ras1 << " " << ras2 << " " << f << endl;
    while(ras1!=f){
        y.pb({{ras1,ras2},ras1});
        if (ras1==1){
            cout << " iuj2" << endl;
        }
        ras1=par[ras1][0];
        k++;
    }
    while(ras2!=f){
        y.pb({{ras2,f},ras2});
        if (ras2==1){
            cout << " iuj4" << endl;
        }
        ras2=par[ras2][0];
        k++;
    }
    cout << ans+k*(k+1)/2 << endl;
    for (int i=0;i<n-1;i++){
        cout << y[i].F.F << " " << y[i].F.S << " " << y[i].S << endl;
    }

}


#include <bits/stdc++.h>
typedef long long int ll;
typedef long double ld;
#define pb push_back
#define pii pair < int , ll >
#define F first
#define S second
#define int long long int
#define sync ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#pragma GCC optimize ("Ofast")
using namespace std;
/*
310 304 317 489 225 131 160 195 197 199 220 203 239 269
407 226 411 415 422 482 520 521 221 222 223 224*/

//const int N=2e5+100;

const int N=2e5+10,M=22;
ll par[N][M];
//ll sub[N];
ll hi[N];
vector <int> g[N];
ll dfs(ll v,ll p,ll h){
    //sub[v]=1;
    hi[v]=h;
    for (int i=0;i<g[v].size();i++){
        ll u=g[v][i];
        if (u!=p){
            par[u][0]=v;
            dfs(u,v,h+1);
           // sub[v]+=sub[u];
        }
    }
   // return sub[v];
}
ll getpar(ll v,ll h){
    if (h==-1 || h==0){
        return v;
    }
    for(int i=0;i<M;i++){
        if (h & (1 << i)) v = par[v][i];
    }
    return v;
}
int lca(int v, int u) {
    if (hi[v]<hi[u]){
        ll y=v;
        v=u;
        u=y;
    }
    v = getpar(v,hi[v]-hi[u]);
    if (v==u){
        return v;
    }
    for(int i=20;i>=0;i--){
        if (par[v][i] != par[u][i]) {
            v=par[v][i];
            u=par[u][i];
        }

    }
    return par[v][0];
}
ll ras1,ras2;
ll ma=0;
ll dfsm(ll v,ll p,ll h){
    if (h>ma){
        ma=h;
        ras1=v;
    }
    for (int i=0;i<g[v].size();i++){
        ll u=g[v][i];
        if (u!=p){
            dfsm(u,v,h+1);
        }
    }
}
ll dfsm1(ll v,ll p,ll h){
    if (h>ma){
        ma=h;
        ras2=v;
    }
    for (int i=0;i<g[v].size();i++){
        ll u=g[v][i];
        if (u!=p){
            dfsm1(u,v,h+1);
        }
    }
}
ll t[N];
ll vis[N];
int32_t main(){
    sync;
    ll n;
    cin >> n ;
    for (int i=0;i<n-1;i++){
        ll u,v;
        cin >> u >> v;
        g[u].pb(v);
        g[v].pb(u);
    }

    dfs(1,1,1);

    for (int i=1;i<M;i++){
        for (int j=1;j<=n;j++){
            par[j][i]=par[par[j][i-1]][i-1];
        }
    }
   // cout << 2 << " " << lca (2,3) << endl;
    dfsm(1,1,1);
    ma=0;
    dfsm1(ras1,ras1,1);
    vector <int> a;
 //   cout << ras1 << " " << ras2 << endl;
    for (int i=1;i<n+1;i++){
        t[i]=g[i].size();
    }

    for (int i=1;i<=n;i++){
        if (t[i]==1 && i!=ras1 && i!=ras2){
            a.pb(i);
        }
    }
    ll ans=0;
    vector <pair <pii,int> > y;
    while(a.size()){
        ll p=a.size();
        ll v=a[p-1];
        ll f1=lca(v,ras1);
        ll f2=lca(v,ras2);
        ll h1=-hi[f1]+hi[v]-hi[f1]+hi[ras1];
        ll h2=-hi[f2]+hi[v]-hi[f2]+hi[ras2];
        if (h1>h2){
            y.pb({{v,ras1},v});
            ans+=h1;
        }
        else{
            y.pb({{v,ras2},v});
            ans+=h2;
        }
      //  cout << v << endl;
        vis[v]=1;
        a.pop_back();
        if (vis[par[v][0]]==1){
            for (int i=0;i<g[v].size();i++){
                ll u=g[v][i];
                t[u]--;
                if (vis[u]==0 && t[u]<=1){
                    a.pb(u);

                }
            }
        }
        else{
            if (v!=1 && t[par[v][0]]<=2){
                //cout << v << " rth " << par[v][0] << endl;
                a.pb(par[v][0]);
                if (v==1){
                    cout << " qifgner;4lm" << endl;
                }
                t[par[v][0]]--;
            }
        }
    }
    ll k=0;
    ll f=lca(ras1,ras2);
   // cout << ans << endl;
   // cout << ras1 << " " << ras2 << " " << f << endl;
    while(ras1!=f){
        y.pb({{ras1,ras2},ras1});
        if (ras1==1){
            cout << " iuj2" << endl;
        }
        ras1=par[ras1][0];
        k++;
    }
    while(ras2!=f){
        y.pb({{ras2,f},ras2});
        if (ras2==1){
            cout << " iuj4" << endl;
        }
        ras2=par[ras2][0];
        k++;
    }
    cout << ans+k*(k+1)/2 << endl;
    for (int i=0;i<n-1;i++){
        cout << y[i].F.F << " " << y[i].F.S << " " << y[i].S << endl;
    }

}


#include <bits/stdc++.h>
typedef long long int ll;
typedef long double ld;
#define pb push_back
#define pii pair < int , ll >
#define F first
#define S second
#define int long long int
#define sync ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#pragma GCC optimize ("Ofast")
using namespace std;
/*
310 304 317 489 225 131 160 195 197 199 220 203 239 269
407 226 411 415 422 482 520 521 221 222 223 224*/

//const int N=2e5+100;

const int N=2e5+10,M=22;
ll par[N][M];
//ll sub[N];
ll hi[N];
vector <int> g[N];
ll dfs(ll v,ll p,ll h){
    //sub[v]=1;
    hi[v]=h;
    for (int i=0;i<g[v].size();i++){
        ll u=g[v][i];
        if (u!=p){
            par[u][0]=v;
            dfs(u,v,h+1);
           // sub[v]+=sub[u];
        }
    }
   // return sub[v];
}
ll getpar(ll v,ll h){
    if (h==-1 || h==0){
        return v;
    }
    for(int i=0;i<M;i++){
        if (h & (1 << i)) v = par[v][i];
    }
    return v;
}
int lca(int v, int u) {
    if (hi[v]<hi[u]){
        ll y=v;
        v=u;
        u=y;
    }
    v = getpar(v,hi[v]-hi[u]);
    if (v==u){
        return v;
    }
    for(int i=20;i>=0;i--){
        if (par[v][i] != par[u][i]) {
            v=par[v][i];
            u=par[u][i];
        }

    }
    return par[v][0];
}
ll ras1,ras2;
ll ma=0;
ll dfsm(ll v,ll p,ll h){
    if (h>ma){
        ma=h;
        ras1=v;
    }
    for (int i=0;i<g[v].size();i++){
        ll u=g[v][i];
        if (u!=p){
            dfsm(u,v,h+1);
        }
    }
}
ll dfsm1(ll v,ll p,ll h){
    if (h>ma){
        ma=h;
        ras2=v;
    }
    for (int i=0;i<g[v].size();i++){
        ll u=g[v][i];
        if (u!=p){
            dfsm1(u,v,h+1);
        }
    }
}
ll t[N];
ll vis[N];
int32_t main(){
    ll n;
    cin >> n ;
    for (int i=0;i<n-1;i++){
        ll u,v;
        cin >> u >> v;
        g[u].pb(v);
        g[v].pb(u);
    }

    dfs(1,1,1);

    for (int i=1;i<M;i++){
        for (int j=1;j<=n;j++){
            par[j][i]=par[par[j][i-1]][i-1];
        }
    }
   // cout << 2 << " " << lca (2,3) << endl;
    dfsm(1,1,1);
    ma=0;
    dfsm1(ras1,ras1,1);
    vector <int> a;
 //   cout << ras1 << " " << ras2 << endl;
    for (int i=1;i<n+1;i++){
        t[i]=g[i].size();
    }

    for (int i=1;i<=n;i++){
        if (t[i]==1 && i!=ras1 && i!=ras2){
            a.pb(i);
        }
    }
    ll ans=0;
    vector <pair <pii,int> > y;
    while(a.size()){
        ll p=a.size();
        ll v=a[p-1];
        ll f1=lca(v,ras1);
        ll f2=lca(v,ras2);
        ll h1=-hi[f1]+hi[v]-hi[f1]+hi[ras1];
        ll h2=-hi[f2]+hi[v]-hi[f2]+hi[ras2];
        if (h1>h2){
            y.pb({{v,ras1},v});
            ans+=h1;
        }
        else{
            y.pb({{v,ras2},v});
            ans+=h2;
        }
      //  cout << v << endl;
        vis[v]=1;
        a.pop_back();
        if (vis[par[v][0]]==1){
            for (int i=0;i<g[v].size();i++){
                ll u=g[v][i];
                if (vis[u]==0){
                    a.pb(u);
                }
            }
        }
    }
    ll k=0;
    ll f=lca(ras1,ras2);
   // cout << ans << endl;
    //cout << ras1 << " " << ras2 << " " << f << endl;
    while(ras1!=f){
        y.pb({{ras1,ras2},ras1});
        ras1=par[ras1][0];
        k++;
    }
    while(ras2!=f){
        y.pb({{ras2,f},ras2});
        ras2=par[ras2][0];
        k++;
    }
    cout << ans+k*(k+1)/2 << endl;
    for (int i=0;i<n-1;i++){
        cout << y[i].F.F << " " << y[i].F.S << " " << y[i].S << endl;
    }

}


#include<bits/stdc++.h>
#define ll long long
#define MAX_N 200010
#define LOGMAXN 20
using namespace std;
ll ans=0;
ll siz[MAX_N]={0};
ll n;
struct edge
{
	ll v,next;
}e[MAX_N<<1];
ll eid,p[MAX_N];
// Cập nhật kiểu để cho dễ duyệt dfs ấy,
// hàm dfs ngay bên dưới.
void insert(ll u,ll v)
{
	e[++eid]={v,p[u]};
	p[u]=eid;
}
ll P[MAX_N][LOGMAXN], T[MAX_N];
ll d[MAX_N][2];// Xác định chiều cao của các đỉnh đỉnh 1 là gốc có chiều cao là 0
void dfs(ll u,ll f,ll idx)
{
	d[u][idx]=d[f][idx]+(f>0);
	for(ll i=p[u];i;i=e[i].next)
	{
		ll v=e[i].v;
		if(f!=v) T[v]=u, dfs(v,u,idx);
	}
}
ll l, r;
void pre_lca(ll N)
{
  ll i, j;

  // Khởi tạo
  for (i = 0; i < N; i++)
    for (j = 0; 1 << j < N; j++)
      P[i][j] = -1;

  // Khởi tạo cha thứ 2^0 = 1 của mỗi nút
  for (i = 1; i <= N; i++)
    P[i][0] = T[i];

  // Quy hoạch động
  for (j = 1; 1 << j < N; j++)
    for (i = 1; i <= N; i++)
      if (P[i][j - 1] != -1)
        P[i][j] = P[P[i][j - 1]][j - 1];
}

ll LCA(ll N, ll u, ll v){
    ll rel_u = u;
    ll rel_v = v;
    if (d[u][0]<d[v][0]) swap(u, v);

    ll log = 19;

    for (ll i=log; i>=0; i--){
        if(d[u][0]- (1<<i) >= d[v][0]){
            u = P[u][i];
        }
    }
    if(u==v) return d[rel_u][0]+d[rel_v][0] - 2*d[u][0];

    for (ll i=log; i>=0; --i){
        if(P[u][i]!=-1 && P[u][i]!=P[v][i]){
            u=P[u][i];
            v=P[v][i];
        }
    }
    ll ancestor = T[u];
    return d[rel_u][0]+d[rel_v][0] - 2*d[ancestor][0];
}
ll maxi;
void chooseLeaves(ll u,ll f, ll maxi)
{
	for(ll i=p[u];i;i=e[i].next)
	{
		ll v=e[i].v;
		if(f!=v) chooseLeaves(v,u, maxi);
	}
    ll tem1 = LCA(n, u, l);
    ll tem2 = LCA(n, u, r);
	if(tem1+tem2!=maxi)
	{
		if(tem1>tem2)cout<<l<<" "<<u<<" "<<u<<endl;
		else cout<<r<<" "<<u<<" "<<u<<endl;
	}
}
void chooseMain(ll u,ll f, ll maxi)
{
	for(ll i=p[u];i;i=e[i].next)
	{
		ll v=e[i].v;
		if(f!=v)chooseMain(v,u,maxi);
	}
    ll tem1 = LCA(n, u, l);
    ll tem2 = LCA(n, u, r);
	if(tem1+tem2==maxi&&u!=l)
		cout<<l<<" "<<u<<" "<<u<<endl;
}
int main(){
    ios::sync_with_stdio(false);
	cin>>n;
	for(ll i=1;i<n;++i)
	{
		ll u,v;
		cin>>u>>v;
        siz[u]++;
        siz[v]++;
		insert(u,v);
		insert(v,u);
	}
	l=1,r=1;
	dfs(1,0,0);
    for(ll i=1;i<=n;++i)if(d[l][0]<d[i][0])l=i;
    //T[1] = 1;
    pre_lca(n);
    maxi = 0;
    /*for (ll i=1; i<=n; ++i){
        if(i!=l){
            ll tem = LCA(n, l, i);
            if (tem>maxi){
                r=i;
                maxi = tem;
            }
        }
    }*/
    dfs(l,0,0); //Duyệt lại chon node vừa nãy làm gốc
	for(ll i=1;i<=n;++i)if(d[r][0]<d[i][0])r=i;
    maxi = d[r][0];
    dfs(1,0,0);
    for(ll u=1;u<=n;++u){
        ll tem1 = LCA(n, u, l);
        ll tem2 = LCA(n, u, r);
		if(tem1+tem2!=maxi)
			ans+=max(tem1,tem2);
    }
	cout<<ans + maxi*(maxi+1)/2<<endl;
    chooseLeaves(l, 0, maxi);
    chooseMain(l, 0, maxi);
    return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define MAX_N 200010
#define LOGMAXN 18
using namespace std;
ll ans=0,siz[MAX_N]={0};
int n;
struct edge
{
	int v,next;
}e[MAX_N<<1];
ll eid,p[MAX_N];
// Cập nhật kiểu để cho dễ duyệt dfs ấy,
// hàm dfs ngay bên dưới.
void insert(int u,int v)
{
	e[++eid]={v,p[u]};
	p[u]=eid;
}
int P[MAX_N][LOGMAXN], T[MAX_N];
ll d[MAX_N][2];// Xác định chiều cao của các đỉnh đỉnh 1 là gốc có chiều cao là 0
void dfs(ll u,ll f,ll idx)
{
	d[u][idx]=d[f][idx]+(f>0);
	for(ll i=p[u];i;i=e[i].next)
	{
		ll v=e[i].v;
		if(f!=v)dfs(v,u,idx), T[v]=u;
	}
}
int l, r;
void pre_lca(int N)
{
  int i, j;

  // Khởi tạo
  for (i = 0; i < N; i++)
    for (j = 0; 1 << j < N; j++)
      P[i][j] = -1;

  // Khởi tạo cha thứ 2^0 = 1 của mỗi nút
  for (i = 1; i <= N; i++)
    P[i][0] = T[i];

  // Quy hoạch động
  for (j = 1; 1 << j < N; j++)
    for (i = 1; i <= N; i++)
      if (P[i][j - 1] != -1)
        P[i][j] = P[P[i][j - 1]][j - 1];
}

int LCA(int N, int u, int v){
    int rel_u = u;
    int rel_v = v;
    if (d[u][0]<d[v][0]) swap(u, v);

    int log =(int) log2(d[u][0]);

    for (int i=log; i>=0; i--){
        if(d[u][0]- (1<<i) >= d[v][0]){
            u = P[u][i];
        }
    }
    if(u==v) return d[rel_u][0]-2*d[u][0]+d[rel_v][0];

    for (int i=log; i>=0; --i){
        if(P[u][i]!=-1 && P[u][i]!=P[v][i]){
            u=P[u][i];
            v=P[v][i];
        }
    }
    int ancestor = T[u];
    return d[rel_u][0]+d[rel_v][0]-2*d[ancestor][0];
}
ll maxi;
void chooseLeaves(ll u,ll f, ll maxi)
{
	for(ll i=p[u];i;i=e[i].next)
	{
		ll v=e[i].v;
		if(f!=v)chooseLeaves(v,u, maxi);
	}
    int tem1 = LCA(n, u, l);
    int tem2 = LCA(n, u, r);
	if(tem1+tem2!=maxi)
	{
		if(tem1>tem2)cout<<l<<" "<<u<<" "<<u<<endl;
		else cout<<r<<" "<<u<<" "<<u<<endl;
	}
}
void chooseMain(ll u,ll f, ll maxi)
{
	for(ll i=p[u];i;i=e[i].next)
	{
		ll v=e[i].v;
		if(f!=v)chooseMain(v,u,maxi);
	}
    int tem1 = LCA(n, u, l);
    int tem2 = LCA(n, u, r);
	if(tem1+tem2==maxi&&u!=l)
		cout<<l<<" "<<u<<" "<<u<<endl;
}
int main(){
    ios::sync_with_stdio(false);
	cin>>n;
	for(int i=1;i<n;++i)
	{
		int u,v;
		cin>>u>>v;
        siz[u]++;
        siz[v]++;
		insert(u,v);
		insert(v,u);
	}
	l=1,r=1;
	dfs(1,0,0);
    for(int i=1;i<=n;++i)if(d[l][0]<d[i][0])l=i;
    //T[1] = 1;
    pre_lca(n);
    maxi = 0;
    for (int i=1; i<=n; ++i){
        if(i!=l && siz[i]==1){
            int tem = LCA(n, l, i);
            if (tem>maxi){
                r=i;
                maxi = tem;
            }
        }
    }
    for(int u=1;u<=n;++u){
        int tem1 = LCA(n, u, l);
        int tem2 = LCA(n, u, r);
		if(tem1+tem2!=maxi)
			ans+=max(tem1,tem2);
    }
	cout<<ans+maxi*(maxi+1)/2<<endl;
    chooseLeaves(l, 0, maxi);
    chooseMain(l, 0, maxi);
}


#include"stdc++.h"
#define ll long long
#define MAX_N 200010
#define LOGMAXN 18
using namespace std;
ll ans=0,siz[MAX_N]={0};
int n;
struct edge
{
	int v,next;
}e[MAX_N<<1];
ll eid,p[MAX_N];
// Cập nhật kiểu để cho dễ duyệt dfs ấy,
// hàm dfs ngay bên dưới.
void insert(int u,int v)
{
	e[++eid]={v,p[u]};
	p[u]=eid;
}
int P[MAX_N][LOGMAXN], T[MAX_N];
ll d[MAX_N][2];// Xác định chiều cao của các đỉnh đỉnh 1 là gốc có chiều cao là 0
void dfs(ll u,ll f,ll idx)
{
	d[u][idx]=d[f][idx]+(f>0);
	for(ll i=p[u];i;i=e[i].next)
	{
		ll v=e[i].v;
		if(f!=v)dfs(v,u,idx), T[v]=u;
	}
}
int l, r;
void pre_lca(int N)
{
  int i, j;

  // Khởi tạo
  for (i = 0; i < N; i++)
    for (j = 0; 1 << j < N; j++)
      P[i][j] = -1;

  // Khởi tạo cha thứ 2^0 = 1 của mỗi nút
  for (i = 1; i <= N; i++)
    P[i][0] = T[i];

  // Quy hoạch động
  for (j = 1; 1 << j < N; j++)
    for (i = 1; i <= N; i++)
      if (P[i][j - 1] != -1)
        P[i][j] = P[P[i][j - 1]][j - 1];
}

int LCA(int N, int u, int v){
    int rel_u = u;
    int rel_v = v;
    if (d[u][0]<d[v][0]) swap(u, v);

    int log =(int) log2(d[u][0]);

    for (int i=log; i>=0; i--){
        if(d[u][0]- (1<<i) >= d[v][0]){
            u = P[u][i];
        }
    }
    if(u==v) return d[rel_u][0]-2*d[u][0]+d[rel_v][0];

    for (int i=log; i>=0; --i){
        if(P[u][i]!=-1 && P[u][i]!=P[v][i]){
            u=P[u][i];
            v=P[v][i];
        }
    }
    int ancestor = T[u];
    return d[rel_u][0]+d[rel_v][0]-2*d[ancestor][0];
}
ll maxi;
void chooseLeaves(ll u,ll f, ll maxi)
{
	for(ll i=p[u];i;i=e[i].next)
	{
		ll v=e[i].v;
		if(f!=v)chooseLeaves(v,u, maxi);
	}
    int tem1 = LCA(n, u, l);
    int tem2 = LCA(n, u, r);
	if(tem1+tem2!=maxi)
	{
		if(tem1>tem2)cout<<l<<" "<<u<<" "<<u<<endl;
		else cout<<r<<" "<<u<<" "<<u<<endl;
	}
}
void chooseMain(ll u,ll f, ll maxi)
{
	for(ll i=p[u];i;i=e[i].next)
	{
		ll v=e[i].v;
		if(f!=v)chooseMain(v,u,maxi);
	}
    int tem1 = LCA(n, u, l);
    int tem2 = LCA(n, u, r);
	if(tem1+tem2==maxi&&u!=l)
		cout<<l<<" "<<u<<" "<<u<<endl;
}
int main(){
    ios::sync_with_stdio(false);
	cin>>n;
	for(int i=1;i<n;++i)
	{
		int u,v;
		cin>>u>>v;
        siz[u]++;
        siz[v]++;
		insert(u,v);
		insert(v,u);
	}
	l=1,r=1;
	dfs(1,0,0);
    for(int i=1;i<=n;++i)if(d[l][0]<d[i][0])l=i;
    //T[1] = 1;
    pre_lca(n);
    maxi = 0;
    for (int i=1; i<=n; ++i){
        if(i!=l && siz[i]==1){
            int tem = LCA(n, l, i);
            if (tem>maxi){
                r=i;
                maxi = tem;
            }
        }
    }
    for(int u=1;u<=n;++u){
        int tem1 = LCA(n, u, l);
        int tem2 = LCA(n, u, r);
		if(tem1+tem2!=maxi)
			ans+=max(tem1,tem2);
    }
	cout<<ans+maxi*(maxi+1)/2<<endl;
    chooseLeaves(l, 0, maxi);
    chooseMain(l, 0, maxi);
}


#include<bits/stdc++.h>
#define ll long long
#define MAX_N 200010
#define LOGMAXN 20
using namespace std;
ll ans=0;
ll siz[MAX_N]={0};
ll n;
struct edge
{
	ll v,next;
}e[MAX_N<<1];
ll eid,p[MAX_N];
// Cập nhật kiểu để cho dễ duyệt dfs ấy,
// hàm dfs ngay bên dưới.
void insert(ll u,ll v)
{
	e[++eid]={v,p[u]};
	p[u]=eid;
}
ll P[MAX_N][LOGMAXN], T[MAX_N];
ll d[MAX_N][2];// Xác định chiều cao của các đỉnh đỉnh 1 là gốc có chiều cao là 0
void dfs(ll u,ll f,ll idx)
{
	d[u][idx]=d[f][idx]+(f>0);
	for(ll i=p[u];i;i=e[i].next)
	{
		ll v=e[i].v;
		if(f!=v) T[v]=u, dfs(v,u,idx);
	}
}
ll l, r;
void pre_lca(ll N)
{
  ll i, j;

  // Khởi tạo
  for (i = 0; i <= N; i++)
    for (j = 0; 1 << j < N; j++)
      P[i][j] = -1;

  // Khởi tạo cha thứ 2^0 = 1 của mỗi nút
  for (i = 0; i <= N; i++)
    P[i][0] = T[i];

  // Quy hoạch động
  for (j = 1; 1 << j < N; j++)
    for (i = 0; i <= N; i++)
      if (P[i][j - 1] != -1)
        P[i][j] = P[P[i][j - 1]][j - 1];
}

ll LCA(ll N, ll u, ll v){
    ll rel_u = u;
    ll rel_v = v;
    if (d[u][0]<d[v][0]) swap(u, v);

    ll log = 19;

    for (ll i=log; i>=0; i--){
        if(d[u][0]- (1<<i) >= d[v][0]){
            u = P[u][i];
        }
    }
    if(u==v){
        return d[rel_u][0]+d[rel_v][0] - 2*d[u][0];
    }
    for (ll i=log; i>=0; --i){
        if(P[u][i]!=-1 && P[u][i]!=P[v][i]){
            u=P[u][i];
            v=P[v][i];
        }
    }
    ll ancestor = T[u];
    return d[rel_u][0]+d[rel_v][0] - 2*d[ancestor][0];
}
ll maxi;
void chooseLeaves(ll u,ll f, ll maxi)
{
	for(ll i=p[u];i;i=e[i].next)
	{
		ll v=e[i].v;
		if(f!=v) chooseLeaves(v,u, maxi);
	}
    ll tem1 = LCA(n, u, l);
    ll tem2 = LCA(n, u, r);
	if(tem1+tem2!=maxi)
	{
		if(tem1>tem2)cout<<l<<" "<<u<<" "<<u<<endl;
		else cout<<r<<" "<<u<<" "<<u<<endl;
	}
}
void chooseMain(ll u,ll f, ll maxi)
{
	for(ll i=p[u];i;i=e[i].next)
	{
		ll v=e[i].v;
		if(f!=v)chooseMain(v,u,maxi);
	}
    ll tem1 = LCA(n, u, l);
    ll tem2 = LCA(n, u, r);
	if(tem1+tem2==maxi&&u!=l)
		cout<<l<<" "<<u<<" "<<u<<endl;
}
int main(){
    ios::sync_with_stdio(false);
	cin>>n;
	for(ll i=1;i<n;++i)
	{
		ll u,v;
		cin>>u>>v;
        siz[u]++;
        siz[v]++;
		insert(u,v);
		insert(v,u);
	}
	l=1,r=1;
	dfs(1,0,0);
    for(ll i=1;i<=n;++i)if(d[l][0]<d[i][0])l=i;
    //T[1] = 1;
    pre_lca(n);
    maxi = 0;
    /*for (ll i=1; i<=n; ++i){
        if(i!=l){
            ll tem = LCA(n, l, i);
            if (tem>maxi){
                r=i;
                maxi = tem;
            }
        }
    }*/
    dfs(l,0,0); //Duyệt lại chon node vừa nãy làm gốc
	for(ll i=1;i<=n;++i)if(d[r][0]<d[i][0])r=i;
    maxi = d[r][0];
    cout<<maxi<<endl;
    dfs(1,0,0);
    for(ll u=1;u<=n;++u){
        ll tem1 = LCA(n, u, l);
        ll tem2 = LCA(n, u, r);
		if(tem1+tem2!=maxi)
			ans+=max(tem1,tem2);
    }
	cout<<ans + maxi*(maxi+1)/2<<endl;
    chooseLeaves(l, 0, maxi);
    chooseMain(l, 0, maxi);
    return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define MAX_N 200010
#define LOGMAXN 20
using namespace std;
ll ans=0;
ll siz[MAX_N]={0};
ll n;
struct edge
{
	ll v,next;
}e[MAX_N<<1];
ll eid,p[MAX_N];
// Cập nhật kiểu để cho dễ duyệt dfs ấy,
// hàm dfs ngay bên dưới.
void insert(ll u,ll v)
{
	e[++eid]={v,p[u]};
	p[u]=eid;
}
ll P[MAX_N][LOGMAXN], T[MAX_N];
ll d[MAX_N][2];// Xác định chiều cao của các đỉnh đỉnh 1 là gốc có chiều cao là 0
void dfs(ll u,ll f,ll idx)
{
	d[u][idx]=d[f][idx]+(f>0);
	for(ll i=p[u];i;i=e[i].next)
	{
		ll v=e[i].v;
		if(f!=v) T[v]=u, dfs(v,u,idx);
	}
}
ll l, r;
void pre_lca(ll N)
{
  ll i, j;

  // Khởi tạo
  for (i = 0; i <= N; i++)
    for (j = 0; 1 << j < N; j++)
      P[i][j] = -1;

  // Khởi tạo cha thứ 2^0 = 1 của mỗi nút
  for (i = 0; i <= N; i++)
    P[i][0] = T[i];

  // Quy hoạch động
  for (j = 1; 1 << j < N; j++)
    for (i = 0; i <= N; i++)
      if (P[i][j - 1] != -1)
        P[i][j] = P[P[i][j - 1]][j - 1];
}

ll LCA(ll N, ll u, ll v){
    ll rel_u = u;
    ll rel_v = v;
    if (d[u][0]<d[v][0]) swap(u, v);

    ll log = 19;

    for (ll i=log; i>=0; i--){
        if(d[u][0]- (1<<i) >= d[v][0]){
            u = P[u][i];
        }
    }
    if(u==v){
        return d[rel_u][0]+d[rel_v][0] - 2*d[u][0];
    }
    for (ll i=log; i>=0; --i){
        if(P[u][i]!=-1 && P[u][i]!=P[v][i]){
            u=P[u][i];
            v=P[v][i];
        }
    }
    ll ancestor = T[u];
    return d[rel_u][0]+d[rel_v][0] - 2*d[ancestor][0];
}
ll maxi;
void chooseLeaves(ll u,ll f, ll maxi)
{
	for(ll i=p[u];i;i=e[i].next)
	{
		ll v=e[i].v;
		if(f!=v) chooseLeaves(v,u, maxi);
	}
    ll tem1 = LCA(n, u, l);
    ll tem2 = LCA(n, u, r);
	if(tem1+tem2!=maxi)
	{
		if(tem1>tem2)cout<<l<<" "<<u<<" "<<u<<endl;
		else cout<<r<<" "<<u<<" "<<u<<endl;
	}
}
void chooseMain(ll u,ll f, ll maxi)
{
	for(ll i=p[u];i;i=e[i].next)
	{
		ll v=e[i].v;
		if(f!=v)chooseMain(v,u,maxi);
	}
    ll tem1 = LCA(n, u, l);
    ll tem2 = LCA(n, u, r);
	if(tem1+tem2==maxi&&u!=l)
		cout<<l<<" "<<u<<" "<<u<<endl;
}
int main(){
    ios::sync_with_stdio(false);
	cin>>n;
	for(ll i=1;i<n;++i)
	{
		ll u,v;
		cin>>u>>v;
        siz[u]++;
        siz[v]++;
		insert(u,v);
		insert(v,u);
	}
	l=1,r=1;
	dfs(1,0,0);
    for(ll i=1;i<=n;++i)if(d[l][0]<d[i][0])l=i;
    //T[1] = 1;
    pre_lca(n);
    maxi = 0;
    /*for (ll i=1; i<=n; ++i){
        if(i!=l){
            ll tem = LCA(n, l, i);
            if (tem>maxi){
                r=i;
                maxi = tem;
            }
        }
    }*/
    dfs(l,0,0); //Duyệt lại chon node vừa nãy làm gốc
	for(ll i=1;i<=n;++i)if(d[r][0]<d[i][0])r=i;
    maxi = d[r][0];
    dfs(1,0,0);
    for(ll u=1;u<=n;++u){
        ll tem1 = LCA(n, u, l);
        ll tem2 = LCA(n, u, r);
		if(tem1+tem2!=maxi)
			ans+=max(tem1,tem2);
    }
	cout<<ans + maxi*(maxi+1)/2<<endl;
    chooseLeaves(l, 0, maxi);
    chooseMain(l, 0, maxi);
}


#include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define pb push_back
#define f(i,x,n) for(int i=x;i<n;i++)
#define all(c) c.begin(),c.end()
#define int ll
using ll = long long;
using pii = pair<int,int>;
const int MOD = 1e9+7, N = 2e5 + 10;

int n;
vector<int> G[N];
int nd[2];
int d[2];
int c;
int dist[2][N];
int deg[N];
int parent[N];

void dfs(int u,int p,int dr){
   if(dr>d[c]){
      nd[c] = u;
      d[c] = dr;
   }
   for(auto &v : G[u]){
      if(v!=p){
         dfs(v,u,dr+1);
      }
   }
}

void dfs(int u,int p){
   dist[c][u] = dist[c][p]+1;
   parent[u] = p;
   for(auto &v : G[u]){
      if(v!=p){
         dfs(v,u);
      }
   }
}

int32_t main(){
   ios::sync_with_stdio(false);
   cin.tie(NULL);
   cin >> n;
   f(i,1,n){
      int u,v;
      cin >> u >> v;
      G[u].pb(v);
      G[v].pb(u);
      deg[u]++;
      deg[v]++;
   }
   dfs(1,0,0);
   c++;
   dfs(nd[0],0,0);
   c = 0;
   dist[c][0] = -1;
   dfs(nd[0],0);
   c++;
   dist[c][0] = -1;
   dfs(nd[1],0);
   unordered_set<int> leaf;
   f(i,1,n+1){
      if(deg[i] == 1 and i!=nd[0] and i!=nd[1]) leaf.insert(i);
   }
   vector<array<int,3>> ans;
   int fin = 0;
   while(!leaf.empty()){
      auto k = *leaf.begin();
      leaf.erase(k);
      if(dist[0][k] >= dist[1][k]){
         ans.pb({nd[0],k,k});
      }else{
         ans.pb({nd[1],k,k});
      }
      fin += max(dist[0][k],dist[1][k]);
      auto par = parent[k];
      deg[par]--;
      if(deg[par]<=1) leaf.insert(par);
   }
   int node = nd[0];
   while(parent[node]){
      fin += dist[1][node];
      ans.pb({nd[1],node,node});
      node = parent[node];
   }
   cout << fin << '\n';
   for(auto &e : ans){
      cout << e[0] << ' ' << e[1] << ' ' << e[2] << '\n';
   }
   return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define pb push_back
#define f(i,x,n) for(int i=x;i<n;i++)
#define all(c) c.begin(),c.end()
#define int ll
using ll = long long;
using pii = pair<int,int>;
const int MOD = 1e9+7, N = 2e5 + 10;

int n;
vector<int> G[N];
int nd[2];
int d[2];
int c;
int dist[2][N];
int deg[N];
int parent[N];

void dfs(int u,int p,int dr){
   if(dr>d[c]){
      nd[c] = u;
      d[c] = dr;
   }
   for(auto &v : G[u]){
      if(v!=p){
         dfs(v,u,dr+1);
      }
   }
}

void dfs(int u,int p){
   dist[c][u] = dist[c][p]+1;
   parent[u] = p;
   for(auto &v : G[u]){
      if(v!=p){
         dfs(v,u);
      }
   }
}

int32_t main(){
   ios::sync_with_stdio(false);
   cin.tie(NULL);
   cin >> n;
   f(i,1,n){
      int u,v;
      cin >> u >> v;
      G[u].pb(v);
      G[v].pb(u);
      deg[u]++;
      deg[v]++;
   }
   dfs(1,0,0);
   c++;
   dfs(nd[0],0,0);
   c = 0;
   dist[c][0] = -1;
   dfs(nd[0],0);
   c++;
   dist[c][0] = -1;
   dfs(nd[1],0);
   vector<int> leaf;
   f(i,1,n+1){
      if(deg[i] == 1 and i!=nd[0] and i!=nd[1]) leaf.pb(i);
   }
   vector<array<int,3>> ans;
   int fin = 0;
   while(!leaf.empty()){
      auto k = leaf.back();
      leaf.pop_back();
      if(dist[0][k] >= dist[1][k]){
         ans.pb({nd[0],k,k});
      }else{
         ans.pb({nd[1],k,k});
      }
      fin += max(dist[0][k],dist[1][k]);
      auto par = parent[k];
      deg[par]--;
      if(deg[par]<=1) leaf.pb(par);
   }
   int node = nd[0];
   while(parent[node]){
      fin += dist[1][node];
      ans.pb({nd[1],node,node});
      node = parent[node];
   }
   cout << fin << '\n';
   for(auto &e : ans){
      cout << e[0] << ' ' << e[1] << ' ' << e[2] << '\n';
   }
   return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define pb push_back
#define f(i,x,n) for(int i=x;i<n;i++)
#define all(c) c.begin(),c.end()
#define int ll
using ll = long long;
using pii = pair<int,int>;
const int MOD = 1e9+7, N = 2e5 + 10;

int n;
vector<int> G[N];
int nd[2];
int d[2];
int c;
int dist[2][N];
int deg[N];
int parent[N];

void dfs(int u,int p,int dr){
   if(dr>d[c]){
      nd[c] = u;
      d[c] = dr;
   }
   for(auto &v : G[u]){
      if(v!=p){
         dfs(v,u,dr+1);
      }
   }
}

void dfs(int u,int p){
   dist[c][u] = dist[c][p]+1;
   parent[u] = p;
   for(auto &v : G[u]){
      if(v!=p){
         dfs(v,u);
      }
   }
}

int32_t main(){
   ios::sync_with_stdio(false);
   cin.tie(NULL);
   cin >> n;
   f(i,1,n){
      int u,v;
      cin >> u >> v;
      G[u].pb(v);
      G[v].pb(u);
      deg[u]++;
      deg[v]++;
   }
   dfs(1,0,0);
   c++;
   dfs(nd[0],0,0);
   c = 0;
   dist[c][0] = -1;
   dfs(nd[0],0);
   c++;
   dist[c][0] = -1;
   dfs(nd[1],0);
   set<int> leaf;
   f(i,1,n+1){
      if(deg[i] == 1 and i!=nd[0] and i!=nd[1]) leaf.insert(i);
   }
   vector<array<int,3>> ans;
   int fin = 0;
   while(!leaf.empty()){
      auto k = *leaf.begin();
      leaf.erase(k);
      if(dist[0][k] >= dist[1][k]){
         ans.pb({nd[0],k,k});
      }else{
         ans.pb({nd[1],k,k});
      }
      fin += max(dist[0][k],dist[1][k]);
      auto par = parent[k];
      deg[par]--;
      if(deg[par]<=1) leaf.insert(par);
   }
   int node = nd[0];
   while(parent[node]){
      fin += dist[1][node];
      ans.pb({nd[1],node,node});
      node = parent[node];
   }
   cout << fin << '\n';
   for(auto &e : ans){
      cout << e[0] << ' ' << e[1] << ' ' << e[2] << '\n';
   }
   return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define int long long
const int inf = 0x3f3f3f3f3f3f3f3LL;
const int mod = (int)1e9 + 7;
using namespace std;
#if LOCAL
#include "../../tr.h"
#else
#define tr(...)
#define endl '\n'
#endif
template<class T, class T2> void smin(T& a, T2 val) {if (a > val) a = val;}template<class T, class T2> void smax(T& a, T2 val) {if (a < val) a = val;}
const int N = 5*(int)1e5 + 10;

int n;
vector<int> v[N];

int depth[N], par[N];

array<int, 2> mxDistance[N];
bool diameter[N];

int mxlvl = -inf, bst = -inf;
int root = -inf;

void dfs(int s, int p, int lvl = 0){
   if (lvl > mxlvl){
      mxlvl = lvl;
      bst = s;
   }
   if (mxDistance[s][0] <= lvl){
      mxDistance[s][0] = lvl;
      mxDistance[s][1] = root;
   }
   for(auto i: v[s]){
      if(i != p){
         dfs(i, s, lvl+1);
      }
   }
}

void dfs2(int s, int p, int lvl = 0){
   depth[s] = lvl;
   par[s] = p;
   for(auto i: v[s]){
      if(i != p){
         dfs2(i, s, lvl+1);
      }
   }
}

vector<int> getPath(int x, int y){

   vector<int> path1, path2;
   path1.push_back(x);
   path2.push_back(y);

   while(x != y){
      tr(x, y);
      if (depth[x] < depth[y]){
         path2.push_back(y = par[y]);
      }
      else if (depth[y] < depth[x]){
         path1.push_back(x = par[x]);
      }
      else{
         path1.push_back(x = par[x]);
         path2.push_back(y = par[y]);
      }
   }

   reverse(path2.begin(), path2.end());
   path2.erase(path2.begin());

   tr(path1, path2);

   for(auto it: path2)
      path1.push_back(it);

   for(auto it: path1)
      diameter[it] = 1;

   return path1;
}

int ret = 0;
vector<array<int, 3>> ans;
void dfs3(int s, int p){
   for(auto i: v[s]){
      if(i != p){
         dfs3(i, s);
      }
   }
   if (!diameter[s]){
      ret += mxDistance[s][0];
      ans.push_back({s, mxDistance[s][1], s});
   }
}

int32_t main(){_

   cin>>n;

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

   int first = -1, second = -1;
   mxlvl = -inf, bst = -inf;
   dfs(1, -1);
   first = bst;
   mxlvl = -inf;
   dfs(bst, -1);
   second = bst;

   root = first;
   dfs(first, -1);
   root = second;
   dfs(second, -1);

   dfs2(1, -1);

   vector<int> path = getPath(first, second);
   tr(path);

   dfs3(1, -1);

   for(auto &it: path){
      mxDistance[it] = {0,0};
   }

   dfs(second, -1);

   int i = 0, j = (int)(path.size())-1;
   while(i < j){
      ret += mxDistance[path[i]][0];
      tr(path[i], mxDistance[path[i]]);
      ans.push_back({path[i], path[j], path[i]});
      ++i;
   }

   cout<<ret<<endl;
   for(auto it: ans){
      cout<<it[0]<<" "<<it[1]<<" "<<it[2]<<endl;
   }

   return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define int long long
const int inf = 0x3f3f3f3f3f3f3f3LL;
const int mod = (int)1e9 + 7;
using namespace std;
#if LOCAL
#include "../../tr.h"
#else
#define tr(...)
#define endl '\n'
#endif
template<class T, class T2> void smin(T& a, T2 val) {if (a > val) a = val;}template<class T, class T2> void smax(T& a, T2 val) {if (a < val) a = val;}
const int N = 5*(int)1e5 + 10;

int n;
vector<int> v[N];

int depth[N], par[N], deg[N];

array<int, 2> mxDistance[N];
bool diameter[N];

queue<int> leafs;
int mxlvl = -inf, bst = -inf;

int root = -inf;

void dfs(int s, int p, int lvl = 0){
   if (lvl > mxlvl){
      mxlvl = lvl;
      bst = s;
   }
   if (mxDistance[s][0] <= lvl){
      mxDistance[s][0] = lvl;
      mxDistance[s][1] = root;
   }
   for(auto i: v[s]){
      if(i != p){
         dfs(i, s, lvl+1);
      }
   }
}

void dfs2(int s, int p, int lvl = 0){
   depth[s] = lvl;
   par[s] = p;
   for(auto i: v[s]){
      if(i != p){
         dfs2(i, s, lvl+1);
      }
   }
}

vector<int> getPath(int x, int y){

   vector<int> path1, path2;
   path1.push_back(x);
   path2.push_back(y);

   while(x != y){
      tr(x, y);
      if (depth[x] < depth[y]){
         path2.push_back(y = par[y]);
      }
      else if (depth[y] < depth[x]){
         path1.push_back(x = par[x]);
      }
      else{
         path1.push_back(x = par[x]);
         path2.push_back(y = par[y]);
      }
   }

   reverse(path2.begin(), path2.end());
   path2.erase(path2.begin());

   tr(path1, path2);

   for(auto it: path2)
      path1.push_back(it);

   for(auto it: path1)
      diameter[it] = 1;

   return path1;
}

int32_t main(){_

   cin>>n;

   for (int i = 0; i+1 < n; ++i)
   {
      int x, y;
      cin >> x >> y;
      deg[x]++, deg[y]++;
      v[x].push_back(y);
      v[y].push_back(x);
   }

   int first = -1, second = -1;
   mxlvl = -inf, bst = -inf;
   dfs(1, -1);
   first = bst;
   mxlvl = -inf;
   dfs(bst, -1);
   second = bst;

   root = first;
   dfs(first, -1);
   root = second;
   dfs(second, -1);

   dfs2(1, -1);

   vector<int> path = getPath(first, second);
   tr(path);

   for (int i = 1; i <= n; ++i)
   {
      if (deg[i] == 1 and !diameter[i]){
         leafs.push(i);
      }
   }

   int ret = 0;
   vector<array<int, 3>> ans;
   while(!leafs.empty()){
      int x = leafs.front();
      leafs.pop();
      ans.push_back({x, mxDistance[x][1], x});
      ret += mxDistance[x][0];
      if (par[x] != -1 and !diameter[par[x]]){
         leafs.push(par[x]);
      }
   }

   for(auto &it: path){
      mxDistance[it] = {0,0};
   }

   dfs(second, -1);

   int i = 0, j = (int)(path.size())-1;
   while(i < j){
      ret += mxDistance[path[i]][0];
      tr(path[i], mxDistance[path[i]]);
      ans.push_back({path[i], path[j], path[i]});
      ++i;
   }

   cout<<ret<<endl;
   for(auto it: ans){
      cout<<it[0]<<" "<<it[1]<<" "<<it[2]<<endl;
   }

   return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define int long long
const int inf = 0x3f3f3f3f3f3f3f3LL;
const int mod = (int)1e9 + 7;
using namespace std;
#if LOCAL
#include "../../tr.h"
#else
#define tr(...)
#define endl '\n'
#endif
template<class T, class T2> void smin(T& a, T2 val) {if (a > val) a = val;}template<class T, class T2> void smax(T& a, T2 val) {if (a < val) a = val;}
const int N = 5*(int)1e5 + 10;

int n;
vector<int> v[N];

int depth[N], par[N];

array<int, 2> mxDistance[N];
bool diameter[N];

int mxlvl = -inf, bst = -inf;
int root = -inf;

void dfs(int s, int p, int lvl = 0){
   if (lvl > mxlvl){
      mxlvl = lvl;
      bst = s;
   }
   if (mxDistance[s][0] <= lvl){
      mxDistance[s][0] = lvl;
      mxDistance[s][1] = root;
   }
   for(auto i: v[s]){
      if(i != p){
         dfs(i, s, lvl+1);
      }
   }
}

void dfs2(int s, int p, int lvl = 0){
   depth[s] = lvl;
   par[s] = p;
   for(auto i: v[s]){
      if(i != p){
         dfs2(i, s, lvl+1);
      }
   }
}

vector<int> getPath(int x, int y){

   vector<int> path1, path2;
   path1.push_back(x);
   path2.push_back(y);

   while(x != y){
      tr(x, y);
      if (depth[x] < depth[y]){
         path2.push_back(y = par[y]);
      }
      else if (depth[y] < depth[x]){
         path1.push_back(x = par[x]);
      }
      else{
         path1.push_back(x = par[x]);
         path2.push_back(y = par[y]);
      }
   }

   reverse(path2.begin(), path2.end());
   path2.erase(path2.begin());

   tr(path1, path2);

   for(auto it: path2)
      path1.push_back(it);

   for(auto it: path1)
      diameter[it] = 1;

   return path1;
}

int ret = 0;
vector<array<int, 3>> ans;
void dfs3(int s, int p){
   for(auto i: v[s]){
      if(i != p){
         dfs3(i, s);
      }
   }
   if (!diameter[s]){
      ret += mxDistance[s][0];
      ans.push_back({s, mxDistance[s][1], s});
   }
}

int32_t main(){_

   cin>>n;

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

   int first = -1, second = -1;
   mxlvl = -inf, bst = -inf;
   dfs(1, -1);
   first = bst;
   mxlvl = -inf;
   dfs(bst, -1);
   second = bst;

   root = first;
   dfs(first, -1);
   root = second;
   dfs(second, -1);

   dfs2(1, -1);

   vector<int> path = getPath(first, second);
   tr(path);

   dfs3(second, -1);

   for(auto &it: path){
      mxDistance[it] = {0,0};
   }

   dfs(second, -1);

   int i = 0, j = (int)(path.size())-1;
   while(i < j){
      ret += mxDistance[path[i]][0];
      tr(path[i], mxDistance[path[i]]);
      ans.push_back({path[i], path[j], path[i]});
      ++i;
   }

   cout<<ret<<endl;
   for(auto it: ans){
      cout<<it[0]<<" "<<it[1]<<" "<<it[2]<<endl;
   }

   return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define int long long
const int inf = 0x3f3f3f3f3f3f3f3LL;
const int mod = (int)1e9 + 7;
using namespace std;
#if LOCAL
#include "../../tr.h"
#else
#define tr(...)
#define endl '\n'
#endif
template<class T, class T2> void smin(T& a, T2 val) {if (a > val) a = val;}template<class T, class T2> void smax(T& a, T2 val) {if (a < val) a = val;}
const int N = 5*(int)1e5 + 10;

int n;
vector<int> v[N];

int depth[N], par[N], deg[N];

array<int, 2> mxDistance[N];
bool diameter[N];

queue<int> leafs;
int mxlvl = -inf, bst = -inf;

int root = -inf;

void dfs(int s, int p, int lvl = 0){
   if (lvl > mxlvl){
      mxlvl = lvl;
      bst = s;
   }
   if (mxDistance[s][0] <= lvl){
      mxDistance[s][0] = lvl;
      mxDistance[s][1] = root;
   }
   depth[s] = lvl;
   par[s] = p;
   for(auto i: v[s]){
      if(i != p){
         dfs(i, s, lvl+1);
      }
   }
}

void dfs2(int s, int p, int lvl = 0){
   depth[s] = lvl;
   par[s] = p;
   for(auto i: v[s]){
      if(i != p){
         dfs2(i, s, lvl+1);
      }
   }
}

vector<int> getPath(int x, int y){

   vector<int> path1, path2;
   path1.push_back(x);
   path2.push_back(y);

   while(x != y){
      tr(x, y);
      if (depth[x] < depth[y]){
         path2.push_back(y = par[y]);
      }
      else if (depth[y] < depth[x]){
         path1.push_back(x = par[x]);
      }
      else{
         path1.push_back(x = par[x]);
         path2.push_back(y = par[y]);
      }
   }

   reverse(path2.begin(), path2.end());
   path2.erase(path2.begin());

   tr(path1, path2);

   for(auto it: path2)
      path1.push_back(it);

   for(auto it: path1)
      diameter[it] = 1;

   return path1;
}

int32_t main(){_

   cin>>n;

   for (int i = 0; i+1 < n; ++i)
   {
      int x, y;
      cin >> x >> y;
      deg[x]++, deg[y]++;
      v[x].push_back(y);
      v[y].push_back(x);
   }

   int first = -1, second = -1;
   mxlvl = -inf, bst = -inf;
   dfs(1, -1);
   first = bst;
   mxlvl = -inf;
   dfs(bst, -1);
   second = bst;

   root = first;
   dfs(first, -1);
   root = second;
   dfs(second, -1);

   dfs2(1, -1);

   vector<int> path = getPath(first, second);
   tr(path);

   dfs(second, -1);

   for (int i = 1; i <= n; ++i)
   {
      if (deg[i] == 1 and !diameter[i]){
         leafs.push(i);
      }
   }

   int ret = 0;
   vector<array<int, 3>> ans;
   while(!leafs.empty()){
      int x = leafs.front();
      leafs.pop();
      ans.push_back({x, mxDistance[x][1], x});
      ret += mxDistance[x][0];
      assert(par[x] != -1);
      if (!diameter[par[x]]){
         leafs.push(par[x]);
      }
   }

   for(auto &it: path){
      mxDistance[it] = {0,0};
   }

   dfs(second, -1);

   int i = 0, j = (int)(path.size())-1;
   while(i < j){
      ret += mxDistance[path[i]][0];
      tr(path[i], mxDistance[path[i]]);
      ans.push_back({path[i], path[j], path[i]});
      ++i;
   }

   cout<<ret<<endl;
   for(auto it: ans){
      cout<<it[0]<<" "<<it[1]<<" "<<it[2]<<endl;
   }

   return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define int long long
const int inf = 0x3f3f3f3f3f3f3f3LL;
const int mod = (int)1e9 + 7;
using namespace std;
#if LOCAL
#include "../../tr.h"
#else
#define tr(...)
#define endl '\n'
#endif
template<class T, class T2> void smin(T& a, T2 val) {if (a > val) a = val;}template<class T, class T2> void smax(T& a, T2 val) {if (a < val) a = val;}
const int N = 5*(int)1e5 + 10;

int n;
vector<int> v[N];

int depth[N], par[N];

array<int, 2> mxDistance[N];
bool diameter[N];

int mxlvl = -inf, bst = -inf;
int root = -inf;

void dfs(int s, int p, int lvl = 0){
   if (lvl > mxlvl){
      mxlvl = lvl;
      bst = s;
   }
   if (mxDistance[s][0] <= lvl){
      mxDistance[s][0] = lvl;
      mxDistance[s][1] = root;
   }
   depth[s] = lvl;
   par[s] = p;
   for(auto i: v[s]){
      if(i != p){
         dfs(i, s, lvl+1);
      }
   }
}

vector<int> getPath(int x, int y){

   vector<int> path1, path2;
   path1.push_back(x);
   path2.push_back(y);

   while(x != y){
      tr(x, y);
      if (depth[x] < depth[y]){
         path2.push_back(y = par[y]);
      }
      else if (depth[y] < depth[x]){
         path1.push_back(x = par[x]);
      }
      else{
         path1.push_back(x = par[x]);
         path2.push_back(y = par[y]);
      }
   }

   reverse(path2.begin(), path2.end());
   path2.erase(path2.begin());

   tr(path1, path2);

   for(auto it: path2)
      path1.push_back(it);

   for(auto it: path1)
      diameter[it] = 1;

   return path1;
}

int ret = 0;
vector<array<int, 3>> ans;
void dfs3(int s, int p, int lvl = 0){
   depth[s] = lvl;
   par[s] = p;
   for(auto i: v[s]){
      if(i != p){
         dfs3(i, s, lvl+1);
      }
   }
   if (!diameter[s]){
      ret += mxDistance[s][0];
      ans.push_back({s, mxDistance[s][1], s});
   }
}

int32_t main(){_

   cin>>n;

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

   int first = -1, second = -1;
   mxlvl = -inf, bst = -inf;
   dfs(1, -1);
   first = bst;
   mxlvl = -inf;
   dfs(bst, -1);
   second = bst;

   root = first;
   dfs(first, -1);
   root = second;
   dfs(second, -1);

   vector<int> path = getPath(first, second);
   dfs3(second, -1);

   int i = 0, j = (int)(path.size())-1;
   while(i < j){
      ret += depth[path[i]];
      ans.push_back({path[i], path[j], path[i]});
      ++i;
   }

   cout<<ret<<endl;
   for(auto it: ans){
      cout<<it[0]<<" "<<it[1]<<" "<<it[2]<<endl;
   }

   return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization ("unroll-loops")
#pragma comment(linker, "/STACK:16777216")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/priority_queue.hpp>

using namespace std;
using namespace __gnu_pbds;

#define LL long long
#define int long long
#define fi first
#define se second
#define pll pair<LL, LL>
#define pii pair<LL, LL>
#define fastio ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define SZ(x) ((int)(x.size()))
#define LC (id<<1)
#define RC (id<<1|1)

constexpr int N = 2e5+9;
constexpr int M = 1e9+7;
constexpr int INF = 0x3f3f3f3f3f3f3f3f;
constexpr int INF2 = 0xcfcfcfcfcfcfcfcf;

int n;
vector<int> g[N];
int fa[N];
vector<int> dia;
int dis[2][N];
int deg[N], isD[N];
int ans;
vector<tuple<int, int, int>> sol;

void findDia() {
    memset(fa, 0, sizeof(fa));
    queue<int> q;
    q.emplace(1);
    int last = 0;
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        last = u;
        for (int v: g[u]) {
            if (v == fa[u]) continue;
            q.emplace(v);
            fa[v] = u;
        }
    }
    memset(fa, 0, sizeof(fa));
    int start = last;
    q.emplace(start);
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        last = u;
        for (int v: g[u]) {
            if (v == fa[u]) continue;
            q.emplace(v);
            fa[v] = u;
        }
    }
    while (last != start) {
        dia.emplace_back(last);
        isD[last] = 1;
        last = fa[last];
    }
    isD[start] = 1;
    dia.emplace_back(start);
}

void bfs(int s, int dis[N]) {
    memset(fa, 0, sizeof(fa));
    queue<int> q;
    q.emplace(s);
    dis[s] = 0;
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        for (int v: g[u]) {
            if (v == fa[u]) continue;
            fa[v] = u;
            dis[v] = dis[u] + 1;
            q.emplace(v);
        }
    }
}

void topSort() {
    memset(fa, 0, sizeof(fa));
    queue<int> q;
    int cnt = 0;
    for (int i = 1; i <= n; i++)
        if (deg[i] == 1 && !isD[i]) q.emplace(i);
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        cnt++;
        if (dis[0][u] > dis[1][u])
            sol.emplace_back(u, dia[0], u);
        else
            sol.emplace_back(u, dia.back(), u);
        ans += max(dis[0][u], dis[1][u]);
        for (int v: g[u]) {
            if (v == fa[u]) continue;
            deg[v]--;
            fa[v] = u;
            if (deg[v] == 1 && !isD[v])
                q.emplace(v);
        }
    }
    assert(cnt == n - SZ(dia));
}

// FST WARNING!!!
// 注意N范围
// 注意除0
// 注意不要超int范围
// 注意分支全部覆盖
// 注意变量不要写错
// 注意清空上个case的影响
// 注意嵌套不要错
// 位运算注意LL
// 检查输入输出格式
// cmp注意相等判断
// 计数问题想好计数依据
// 先复核，后提交

signed main() {
    fastio;
    cin >> n;
    for (int i = 1; i < n; i++) {
        int u, v;
        cin >> u >> v;
        g[u].emplace_back(v);
        g[v].emplace_back(u);
        deg[u]++;
        deg[v]++;
    }
    findDia();
    bfs(dia[0], dis[0]);
    bfs(dia.back(), dis[1]);
    topSort();
    while (SZ(dia) > 1) {
        sol.emplace_back(dia.back(), dia[0], dia.back());
        dia.pop_back();
        ans += SZ(dia);
    }
    cout << ans << "\n";
    for (const auto&[a, b, c]: sol) {
        cout << a << " " << b << " " << c << "\n";
    }
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization ("unroll-loops")
#pragma comment(linker, "/STACK:16777216")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/priority_queue.hpp>

using namespace std;
using namespace __gnu_pbds;

#define LL long long
#define int long long
#define fi first
#define se second
#define pll pair<LL, LL>
#define pii pair<LL, LL>
#define fastio ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define SZ(x) ((int)(x.size()))
#define LC (id<<1)
#define RC (id<<1|1)

constexpr int N = 2e5+9;
constexpr int M = 1e9+7;
constexpr int INF = 0x3f3f3f3f3f3f3f3f;
constexpr int INF2 = 0xcfcfcfcfcfcfcfcf;

int n;
vector<int> g[N];
int fa[N];
vector<int> dia;
int dis[2][N];
int deg[N], isD[N];
int ans;
vector<tuple<int, int, int>> sol;

void findDia() {
    queue<int> q;
    q.emplace(1);
    int last = 0;
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        last = u;
        for (int v: g[u]) {
            if (v == fa[u]) continue;
            q.emplace(v);
            fa[v] = u;
        }
    }
    memset(fa, 0, sizeof(fa));
    int start = last;
    q.emplace(start);
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        last = u;
        for (int v: g[u]) {
            if (v == fa[u]) continue;
            q.emplace(v);
            fa[v] = u;
        }
    }
    while (last != start) {
        dia.emplace_back(last);
        isD[last] = 1;
        last = fa[last];
    }
    isD[start] = 1;
    dia.emplace_back(start);
}

void bfs(int s, int dis[N]) {
    memset(fa, 0, sizeof(fa));
    memset(dis, 0x3f, sizeof(int)*N);
    queue<int> q;
    q.emplace(s);
    dis[s] = 0;
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        for (int v: g[u]) {
            if (v == fa[u]) continue;
            fa[v] = u;
            dis[v] = dis[u] + 1;
            q.emplace(v);
        }
    }
}

void topSort() {
    queue<int> q;
    for (int i = 1; i <= n; i++)
        if (deg[i] == 1 && !isD[i]) q.emplace(i);
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        if (dis[0][u] > dis[1][u])
            sol.emplace_back(u, dia[0], u);
        else
            sol.emplace_back(u, dia.back(), u);
        ans += max(dis[0][u], dis[1][u]);
        for (int v: g[u]) {
            deg[v]--;
            if (deg[v] == 1 && !isD[v])
                q.emplace(v);
        }
    }
}

// FST WARNING!!!
// 注意N范围
// 注意除0
// 注意不要超int范围
// 注意分支全部覆盖
// 注意变量不要写错
// 注意清空上个case的影响
// 注意嵌套不要错
// 位运算注意LL
// 检查输入输出格式
// cmp注意相等判断
// 计数问题想好计数依据
// 先复核，后提交

signed main() {
    fastio;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        int u, v;
        cin >> u >> v;
        g[u].emplace_back(v);
        g[v].emplace_back(u);
        deg[u]++;
        deg[v]++;
    }
    findDia();
    bfs(dia[0], dis[0]);
    bfs(dia.back(), dis[1]);
    topSort();
    while (SZ(dia) > 1) {
        sol.emplace_back(dia.back(), dia[0], dia.back());
        dia.pop_back();
        ans += SZ(dia);
    }
    cout << ans << "\n";
    for (const auto&[a, b, c]: sol) {
        cout << a << " " << b << " " << c << "\n";
    }
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization ("unroll-loops")
#pragma comment(linker, "/STACK:16777216")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/priority_queue.hpp>

using namespace std;
using namespace __gnu_pbds;

#define LL long long
#define int long long
#define fi first
#define se second
#define pll pair<LL, LL>
#define pii pair<LL, LL>
#define fastio ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define SZ(x) ((int)(x.size()))
#define LC (id<<1)
#define RC (id<<1|1)

constexpr int N = 2e5+9;
constexpr int M = 1e9+7;
constexpr int INF = 0x3f3f3f3f3f3f3f3f;
constexpr int INF2 = 0xcfcfcfcfcfcfcfcf;

int n;
vector<int> g[N];
int fa[N];
vector<int> dia;
int dis[2][N];
int deg[N], isD[N];
int ans;
vector<tuple<int, int, int>> sol;

void findDia() {
    memset(fa, 0, sizeof(fa));
    queue<int> q;
    q.emplace(1);
    int last = 0;
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        last = u;
        for (int v: g[u]) {
            if (v == fa[u]) continue;
            q.emplace(v);
            fa[v] = u;
        }
    }
    memset(fa, 0, sizeof(fa));
    int start = last;
    q.emplace(start);
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        last = u;
        for (int v: g[u]) {
            if (v == fa[u]) continue;
            q.emplace(v);
            fa[v] = u;
        }
    }
    while (last != start) {
        dia.emplace_back(last);
        isD[last] = 1;
        last = fa[last];
    }
    isD[start] = 1;
    dia.emplace_back(start);
}

void bfs(int s, int dis[N]) {
    memset(fa, 0, sizeof(fa));
    queue<int> q;
    q.emplace(s);
    dis[s] = 0;
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        for (int v: g[u]) {
            if (v == fa[u]) continue;
            fa[v] = u;
            dis[v] = dis[u] + 1;
            q.emplace(v);
        }
    }
}

void topSort() {
    queue<int> q;
    int cnt = 0;
    for (int i = 1; i <= n; i++)
        if (deg[i] == 1 && !isD[i]) q.emplace(i);
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        cnt++;
        if (dis[0][u] > dis[1][u])
            sol.emplace_back(u, dia[0], u);
        else
            sol.emplace_back(u, dia.back(), u);
        ans += max(dis[0][u], dis[1][u]);
        for (int v: g[u]) {
            deg[v]--;
            if (deg[v] == 1 && !isD[v])
                q.emplace(v);
        }
    }
    assert(cnt == n - SZ(dia));
}

// FST WARNING!!!
// 注意N范围
// 注意除0
// 注意不要超int范围
// 注意分支全部覆盖
// 注意变量不要写错
// 注意清空上个case的影响
// 注意嵌套不要错
// 位运算注意LL
// 检查输入输出格式
// cmp注意相等判断
// 计数问题想好计数依据
// 先复核，后提交

signed main() {
    fastio;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        int u, v;
        cin >> u >> v;
        g[u].emplace_back(v);
        g[v].emplace_back(u);
        deg[u]++;
        deg[v]++;
    }
    findDia();
    bfs(dia[0], dis[0]);
    bfs(dia.back(), dis[1]);
    topSort();
    while (SZ(dia) > 1) {
        sol.emplace_back(dia.back(), dia[0], dia.back());
        dia.pop_back();
        ans += SZ(dia);
    }
    cout << ans << "\n";
    for (const auto&[a, b, c]: sol) {
        cout << a << " " << b << " " << c << "\n";
    }
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization ("unroll-loops")
#pragma comment(linker, "/STACK:16777216")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/priority_queue.hpp>

using namespace std;
using namespace __gnu_pbds;

#define LL long long
#define int long long
#define fi first
#define se second
#define pll pair<LL, LL>
#define pii pair<LL, LL>
#define fastio ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define SZ(x) ((int)(x.size()))
#define LC (id<<1)
#define RC (id<<1|1)

constexpr int N = 2e5+9;
constexpr int M = 1e9+7;
constexpr int INF = 0x3f3f3f3f3f3f3f3f;
constexpr int INF2 = 0xcfcfcfcfcfcfcfcf;

int n;
vector<int> g[N];
int fa[N];
vector<int> dia;
int dis[2][N];
int deg[N], isD[N];
int ans;
vector<tuple<int, int, int>> sol;

void findDia() {
    memset(fa, 0, sizeof(fa));
    queue<int> q;
    q.emplace(1);
    int last = 0;
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        last = u;
        for (int v: g[u]) {
            if (v == fa[u]) continue;
            q.emplace(v);
            fa[v] = u;
        }
    }
    memset(fa, 0, sizeof(fa));
    int start = last;
    q.emplace(start);
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        last = u;
        for (int v: g[u]) {
            if (v == fa[u]) continue;
            q.emplace(v);
            fa[v] = u;
        }
    }
    while (last != start) {
        dia.emplace_back(last);
        isD[last] = 1;
        last = fa[last];
    }
    isD[start] = 1;
    dia.emplace_back(start);
}

void bfs(int s, int dis[N]) {
    memset(fa, 0, sizeof(fa));
    queue<int> q;
    q.emplace(s);
    dis[s] = 0;
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        for (int v: g[u]) {
            if (v == fa[u]) continue;
            fa[v] = u;
            dis[v] = dis[u] + 1;
            q.emplace(v);
        }
    }
}

void topSort() {
    memset(fa, 0, sizeof(fa));
    queue<int> q;
    int cnt = 0;
    for (int i = 1; i <= n; i++)
        if (deg[i] == 1 && !isD[i]) q.emplace(i);
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        cnt++;
        if (dis[0][u] > dis[1][u])
            sol.emplace_back(u, dia[0], u);
        else
            sol.emplace_back(u, dia.back(), u);
        ans += max(dis[0][u], dis[1][u]);
        for (int v: g[u]) {
            if (v == fa[u]) continue;
            deg[v]--;
            fa[v] = u;
            if (deg[v] == 1 && !isD[v])
                q.emplace(v);
        }
    }
    assert(cnt == n - SZ(dia));
}

// FST WARNING!!!
// 注意N范围
// 注意除0
// 注意不要超int范围
// 注意分支全部覆盖
// 注意变量不要写错
// 注意清空上个case的影响
// 注意嵌套不要错
// 位运算注意LL
// 检查输入输出格式
// cmp注意相等判断
// 计数问题想好计数依据
// 先复核，后提交

signed main() {
    fastio;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        int u, v;
        cin >> u >> v;
        g[u].emplace_back(v);
        g[v].emplace_back(u);
        deg[u]++;
        deg[v]++;
    }
    findDia();
    bfs(dia[0], dis[0]);
    bfs(dia.back(), dis[1]);
    topSort();
    while (SZ(dia) > 1) {
        sol.emplace_back(dia.back(), dia[0], dia.back());
        dia.pop_back();
        ans += SZ(dia);
    }
    cout << ans << "\n";
    for (const auto&[a, b, c]: sol) {
        cout << a << " " << b << " " << c << "\n";
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define SZ(a) ((int)(a).size())
#define PB push_back
#define MP make_pair
const int maxn = 200009;
const int MOD = 1e9 + 7;
set<int> V[maxn];
int dep[maxn],st,ed,dist;
void dfs(int u,int fa,int d=0){
  dep[u]=d;
  if(dep[u]>dist){
    dist=dep[u];
    ed=u;
  }
  for(int v:V[u])if(v!=fa){
    dfs(v,u,d+1);
  }
}
void dfs2(int u,int fa,vector<int> &dis){
  for(int v:V[u])if(v!=fa){
    dis[v]=dis[u]+1;
    dfs2(v,u,dis);
  }
}
int main(){
#ifdef LOCAL
  freopen("a.in", "r", stdin);
#endif
  ios_base::sync_with_stdio(false),cout.tie(0),cin.tie(0);
  int n;cin>>n;
  for(int i=1;i<n;++i){
    int u,v;cin>>u>>v;
    V[u].insert(v);
    V[v].insert(u);
  }
  dist=-1;
  dfs(1,1);
  st=ed;
  dist=-1;
  dfs(ed,ed);
  vector<int> DISTST(n+1),DISTED(n+1);
  dfs2(st,st,DISTST);
  dfs2(ed,ed,DISTED);
  vector<int> que;
  for(int i=1;i<=n;++i)if(i!=st&&i!=ed&&SZ(V[i])==1){
    que.PB(i);
  }
  vector<pair<pair<int,int>,int>> ans;
  int64_t tot=0;
  for(int i=0;i<SZ(que);++i){
    if(DISTST[que[i]]>=DISTED[que[i]]){
      tot+=DISTST[que[i]];
      ans.PB(MP(MP(st,que[i]),que[i]));
    }else{
      tot+=DISTED[que[i]];
      ans.PB(MP(MP(ed,que[i]),que[i]));
    }
      for(int v:V[que[i]]){
        V[v].erase(que[i]);
        if(SZ(V[v])==1)que.PB(v);
      }
  }
  for(int i=DISTST[ed];i>=1;--i){
    tot+=i;
    int a=*V[ed].begin();
    V[a].erase(ed);
    ans.PB(MP(MP(ed,st),ed));
    ed=a;
  }
  cout<<tot<<"\n";
  for(auto i:ans){
    cout<<i.first.first<<" "<<i.first.second<<" "<<i.second<<'\n';
  }
  return 0;
}
//2020.07.07 19:24:43


#include <bits/stdc++.h>
using namespace std;
#define SZ(a) ((int)(a).size())
#define PB push_back
#define MP make_pair
const int maxn = 200009;
const int MOD = 1e9 + 7;
set<int> V[maxn];
int dep[maxn],st,ed,dist;
void dfs(int u,int fa,int d=0){
  dep[u]=d;
  if(dep[u]>dist){
    dist=dep[u];
    ed=u;
  }
  for(int v:V[u])if(v!=fa){
    dfs(v,u,d+1);
  }
}
void dfs2(int u,int fa,vector<int> &dis){
  for(int v:V[u])if(v!=fa){
    dis[v]=dis[u]+1;
    dfs2(v,u,dis);
  }
}
int main(){
#ifdef LOCAL
  freopen("a.in", "r", stdin);
#endif
  ios_base::sync_with_stdio(false),cout.tie(0),cin.tie(0);
  int n;cin>>n;
  for(int i=1;i<n;++i){
    int u,v;cin>>u>>v;
    V[u].insert(v);
    V[v].insert(u);
  }
  dist=-1;
  dfs(1,1);
  st=ed;
  dist=-1;
  dfs(ed,ed);
  vector<int> DISTST(n+1),DISTED(n+1);
  dfs2(st,st,DISTST);
  dfs2(ed,ed,DISTED);
  vector<int> que;
  for(int i=1;i<=n;++i)if(i!=st&&i!=ed&&SZ(V[i])==1){
    que.PB(i);
  }
  vector<pair<pair<int,int>,int>> ans;
  int tot=0;
  for(int i=0;i<SZ(que);++i){
    if(DISTST[que[i]]>=DISTED[que[i]]){
      tot+=DISTST[que[i]];
      ans.PB(MP(MP(st,que[i]),que[i]));
    }else{
      tot+=DISTED[que[i]];
      ans.PB(MP(MP(ed,que[i]),que[i]));
    }
      for(int v:V[que[i]]){
        V[v].erase(que[i]);
        if(SZ(V[v])==1)que.PB(v);
      }
  }
  for(int i=DISTST[ed];i>=1;--i){
    tot+=i;
    int a=*V[ed].begin();
    V[a].erase(ed);
    ans.PB(MP(MP(ed,st),ed));
    ed=a;
  }
  cout<<tot<<"\n";
  for(auto i:ans){
    cout<<i.first.first<<" "<<i.first.second<<" "<<i.second<<'\n';
  }
  return 0;
}
//2020.07.07 19:24:43


#include <bits/stdc++.h>
using namespace std;
#define SZ(a) ((int)(a).size())
#define PB push_back
#define MP make_pair
const int maxn = 200009;
const int MOD = 1e9 + 7;
set<int> V[maxn];
int dep[maxn],st,ed,dist;
void dfs(int u,int fa,int d=0){
  dep[u]=d;
  if(dep[u]>dist){
    dist=dep[u];
    ed=u;
  }
  for(int v:V[u])if(v!=fa){
    dfs(v,u,d+1);
  }
}
void dfs2(int u,int fa,vector<int> &dis){
  for(int v:V[u])if(v!=fa){
    dis[v]=dis[u]+1;
    dfs2(v,u,dis);
  }
}
int main(){
#ifdef LOCAL
  freopen("a.in", "r", stdin);
#endif
  ios_base::sync_with_stdio(false),cout.tie(0),cin.tie(0);
  int n;cin>>n;
  for(int i=1;i<n;++i){
    int u,v;cin>>u>>v;
    V[u].insert(v);
    V[v].insert(u);
  }
  dist=-1;
  dfs(1,1);
  st=ed;
  dist=-1;
  dfs(ed,ed);
  vector<int> DISTST(n+1),DISTED(n+1);
  dfs2(st,st,DISTST);
  dfs2(ed,ed,DISTED);
  vector<int> que;
  for(int i=1;i<=n;++i)if(i!=st&&i!=ed&&SZ(V[i])==1){
    que.PB(i);
  }
  vector<pair<pair<int,int>,int>> ans;
  int tot=0;
  for(int i=0;i<SZ(que);++i){
    if(DISTST[que[i]]>=DISTED[que[i]]){
      tot+=DISTST[que[i]];
      ans.PB(MP(MP(st,que[i]),que[i]));
    }else{
      tot+=DISTED[que[i]];
      ans.PB(MP(MP(ed,que[i]),que[i]));
    }
      for(int v:V[que[i]]){
        V[v].erase(que[i]);
        if(SZ(V[v])==1)que.PB(v);
      }
  }
  for(int i=DISTST[ed];i>=1;--i){
    tot+=i;
    int a=*V[ed].begin();
    V[a].erase(ed);
    ans.PB(MP(MP(ed,a),ed));
    ed=a;
  }
  cout<<tot<<"\n";
  for(auto i:ans){
    cout<<i.first.first<<" "<<i.first.second<<" "<<i.second<<'\n';
  }
  return 0;
}
//2020.07.07 19:24:43


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

int n;
vector < int > E[200005];
int dist[200005],pi[200005];
int st , ed;
int mark[200005];
int pa[19][200005];
int Depth[200005];
queue < int > q;
int A[200005], B[200005], C[200005];
int idx = 0;

void dfs( int u , int p, int d ){
	pa[0][u] = p;
	Depth[u] = d;
	for ( int i = 1; i < 19; i++ ){
		if ( pa[i-1][u] != -1 ) pa[i][u] = pa[i-1][pa[i-1][u]];
	}
	for ( int v : E[u] ){
		if ( v != p ) dfs(v,u,d+1);
	}
}

void findDiameter(){
	memset(dist,-1,sizeof(dist));
	dist[1] = 0;
	q.push(1);
	int far = 1;
	while ( !q.empty() ){
		int u = q.front();
		q.pop();
		far = u;
		for ( int v : E[u] ){
			if ( dist[v] == -1 ){
				dist[v] = dist[u] + 1;
				q.push(v);
			}
		}
	}
	memset(dist,-1,sizeof(dist));
	memset(pi,-1,sizeof(pi));
	st = far;
	dist[st] = 0;
	q.push(st);
	while ( !q.empty() ){
		int u = q.front();
		q.pop();
		far = u;
		for ( int v : E[u] ){
			if ( dist[v] == -1 ){
				dist[v] = dist[u] + 1;
				q.push(v);
				pi[v] = u;
			}
		}
	}

	ed = far;
	int bt = far;
	while ( bt != -1 ){
		mark[bt] = true;
		bt = pi[bt];
	}
}

int LCA( int u , int v ){
	if ( Depth[u] < Depth[v] ) swap(u,v);
	int diff = Depth[u] - Depth[v];
	for ( int i = 0; i < 19; i++ ){
		if ( (diff>>i) & 1 ){
			u = pa[i][u];
		}
	}
	if ( u == v ) return u;

	for ( int i = 0; i < 19; i++ ){
		if ( pa[i][u] != pa[i][v] ){
			u = pa[i][u];
			v = pa[i][v];
		}
	}
	return pa[0][u];
}

LL Dist( int u, int v ){
	int lca = LCA(u,v);
	return Depth[u] + Depth[v] - 2 * 1LL * Depth[lca];
}

LL solve( int u, int p ){
	LL ans = 0;
	for ( int v : E[u] ){
		if ( v != p ) ans += solve(v,u);
	}
	if ( !mark[u] ){
		if ( Dist(st,u) > Dist(ed,u) ){
			ans += Dist(st,u);
			idx++;
			A[idx] = st;
			B[idx] = u;
			C[idx] = u;
		} else {
			ans += Dist(ed,u);
			idx++;
			A[idx] = ed;
			B[idx] = u;
			C[idx] = u;
		}
	}
	return ans;
}

int main(){

	memset(pa,-1,sizeof(pa));
	scanf("%d",&n);
	for ( int i = 0; i < n-1; i++ ){
		int u , v;
		scanf("%d%d",&u,&v);
		E[u].push_back(v);
		E[v].push_back(u);
	}
	dfs(1,-1,0);
	findDiameter();

	LL ans = solve(1,-1);

	int id = ed;
	while ( id != st ){
		ans += dist[id];
		idx++;
		A[idx] = id;
		B[idx] = st;
		C[idx] = id;
		id = pi[id];
	}

	printf("%lld\n",ans);
	for ( int i = 1; i < n; i++ ){
		printf("%d %d %d\n",A[i], B[i], C[i]);
	}
	return 0;
}


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

int n;
vector < int > E[200005];
int dist[200005],pi[200005];
int st , ed;
int mark[200005];
int pa[200005][19];
int Depth[200005];
queue < int > q;
int A[200005], B[200005], C[200005];
int idx = 0;

void dfs( int u , int p, int d ){
	pa[0][u] = p;
	Depth[u] = d;
	for ( int i = 1; i < 19; i++ ){
		if ( pa[i-1][u] != -1 ) pa[i][u] = pa[i-1][pa[i-1][u]];
	}
	for ( int v : E[u] ){
		if ( v != p ) dfs(v,u,d+1);
	}
}

void findDiameter(){
	memset(dist,-1,sizeof(dist));
	dist[1] = 0;
	q.push(1);
	int far = 1;
	while ( !q.empty() ){
		int u = q.front();
		q.pop();
		far = u;
		for ( int v : E[u] ){
			if ( dist[v] == -1 ){
				dist[v] = dist[u] + 1;
				q.push(v);
			}
		}
	}
	memset(dist,-1,sizeof(dist));
	memset(pi,-1,sizeof(pi));
	st = far;
	dist[st] = 0;
	q.push(st);
	while ( !q.empty() ){
		int u = q.front();
		q.pop();
		far = u;
		for ( int v : E[u] ){
			if ( dist[v] == -1 ){
				dist[v] = dist[u] + 1;
				q.push(v);
				pi[v] = u;
			}
		}
	}

	ed = far;
	int bt = far;
	while ( bt != -1 ){
		mark[bt] = true;
		bt = pi[bt];
	}
}

int LCA( int u , int v ){
	if ( Depth[u] < Depth[v] ) swap(u,v);
	int diff = Depth[u] - Depth[v];
	for ( int i = 0; i < 19; i++ ){
		if ( (diff>>i) & 1 ){
			u = pa[i][u];
		}
	}
	if ( u == v ) return u;

	for ( int i = 0; i < 19; i++ ){
		if ( pa[i][u] != pa[i][v] ){
			u = pa[i][u];
			v = pa[i][v];
		}
	}
	return pa[0][u];
}

LL Dist( int u, int v ){
	int lca = LCA(u,v);
	return Depth[u] + Depth[v] - 2 * 1LL * Depth[lca];
}

LL solve( int u, int p ){
	LL ans = 0;
	for ( int v : E[u] ){
		if ( v != p ) ans += solve(v,u);
	}
	if ( !mark[u] ){
		if ( Dist(st,u) > Dist(ed,u) ){
			ans += Dist(st,u);
			idx++;
			A[idx] = st;
			B[idx] = u;
			C[idx] = u;
		} else {
			ans += Dist(ed,u);
			idx++;
			A[idx] = ed;
			B[idx] = u;
			C[idx] = u;
		}
	}
	return ans;
}

int main(){

	memset(pa,-1,sizeof(pa));
	scanf("%d",&n);
	for ( int i = 0; i < n-1; i++ ){
		int u , v;
		scanf("%d%d",&u,&v);
		E[u].push_back(v);
		E[v].push_back(u);
	}
	dfs(1,-1,0);
	findDiameter();

	LL ans = solve(1,-1);

	int id = ed;
	while ( id != st ){
		ans += dist[id];
		idx++;
		A[idx] = id;
		B[idx] = st;
		C[idx] = id;
		id = pi[id];
	}

	printf("%lld\n",ans);
	for ( int i = 1; i < n; i++ ){
		printf("%d %d %d\n",A[i], B[i], C[i]);
	}
	return 0;
}


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

int n;
vector < int > E[200005];
int dist[200005],pi[200005];
int st , ed;
int mark[200005];
int pa[20][200005];
int Depth[200005];
queue < int > q;
int A[200005], B[200005], C[200005];
int idx = 0;

void dfs( int u , int p, int d ){
	pa[0][u] = p;
	Depth[u] = d;
	for ( int i = 1; i < 20; i++ ){
		if ( pa[i-1][u] != -1 ) pa[i][u] = pa[i-1][pa[i-1][u]];
	}
	for ( int v : E[u] ){
		if ( v != p ) dfs(v,u,d+1);
	}
}

void findDiameter(){
	memset(dist,-1,sizeof(dist));
	dist[1] = 0;
	q.push(1);
	int far = 1;
	while ( !q.empty() ){
		int u = q.front();
		q.pop();
		far = u;
		for ( int v : E[u] ){
			if ( dist[v] == -1 ){
				dist[v] = dist[u] + 1;
				q.push(v);
			}
		}
	}
	memset(dist,-1,sizeof(dist));
	memset(pi,-1,sizeof(pi));
	st = far;
	dist[st] = 0;
	q.push(st);
	while ( !q.empty() ){
		int u = q.front();
		q.pop();
		far = u;
		for ( int v : E[u] ){
			if ( dist[v] == -1 ){
				dist[v] = dist[u] + 1;
				q.push(v);
				pi[v] = u;
			}
		}
	}

	ed = far;
	int bt = far;
	while ( bt != -1 ){
		mark[bt] = true;
		bt = pi[bt];
	}
}

int LCA( int u , int v ){
	if ( Depth[u] < Depth[v] ) swap(u,v);
	int diff = Depth[u] - Depth[v];
	for ( int i = 0; i < 20; i++ ){
		if ( (diff>>i) & 1 ){
			u = pa[i][u];
		}
	}
	if ( u == v ) return u;

	for ( int i = 19; i >= 0; i-- ){
		if ( pa[i][u] != pa[i][v] ){
			u = pa[i][u];
			v = pa[i][v];
		}
	}
	return pa[0][u];
}

LL Dist( int u, int v ){
	int lca = LCA(u,v);
	return Depth[u] + Depth[v] - 2 * 1LL * Depth[lca];
}

LL solve( int u, int p ){
	LL ans = 0;
	for ( int v : E[u] ){
		if ( v != p ) ans += solve(v,u);
	}
	if ( !mark[u] ){
		if ( Dist(st,u) > Dist(ed,u) ){
			ans += Dist(st,u);
			idx++;
			A[idx] = st;
			B[idx] = u;
			C[idx] = u;
		} else {
			ans += Dist(ed,u);
			idx++;
			A[idx] = ed;
			B[idx] = u;
			C[idx] = u;
		}
	}
	return ans;
}

int main(){

	memset(pa,-1,sizeof(pa));
	scanf("%d",&n);
	for ( int i = 0; i < n-1; i++ ){
		int u , v;
		scanf("%d%d",&u,&v);
		E[u].push_back(v);
		E[v].push_back(u);
	}
	dfs(1,-1,0);
	findDiameter();

	LL ans = solve(1,-1);
	int id = ed;
	while ( id != st ){
		ans += dist[id];
		idx++;
		A[idx] = id;
		B[idx] = st;
		C[idx] = id;
		id = pi[id];
	}

	printf("%lld\n",ans);
	for ( int i = 1; i < n; i++ ){
		printf("%d %d %d\n",A[i], B[i], C[i]);
	}
	return 0;
}


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

int n;
vector < int > E[200005];
int dist[200005],pi[200005];
int st , ed;
int mark[200005];
int pa[22][200005];
int Depth[200005];
queue < int > q;
int A[200005], B[200005], C[200005];
int idx = 0;

void dfs( int u , int p, int d ){
	pa[0][u] = p;
	Depth[u] = d;
	for ( int i = 1; i < 21; i++ ){
		if ( pa[i-1][u] != -1 ) pa[i][u] = pa[i-1][pa[i-1][u]];
	}
	for ( int v : E[u] ){
		if ( v != p ) dfs(v,u,d+1);
	}
}

void findDiameter(){
	memset(dist,-1,sizeof(dist));
	dist[1] = 0;
	q.push(1);
	int far = 1;
	while ( !q.empty() ){
		int u = q.front();
		q.pop();
		far = u;
		for ( int v : E[u] ){
			if ( dist[v] == -1 ){
				dist[v] = dist[u] + 1;
				q.push(v);
			}
		}
	}
	memset(dist,-1,sizeof(dist));
	memset(pi,-1,sizeof(pi));
	st = far;
	dist[st] = 0;
	q.push(st);
	while ( !q.empty() ){
		int u = q.front();
		q.pop();
		far = u;
		for ( int v : E[u] ){
			if ( dist[v] == -1 ){
				dist[v] = dist[u] + 1;
				q.push(v);
				pi[v] = u;
			}
		}
	}

	ed = far;
	int bt = far;
	while ( bt != -1 ){
		mark[bt] = true;
		bt = pi[bt];
	}
}

int LCA( int u , int v ){
	if ( Depth[u] < Depth[v] ) swap(u,v);
	int diff = Depth[u] - Depth[v];
	for ( int i = 20; i >= 0; i-- ){
		if ( (diff>>i) & 1 ){
			u = pa[i][u];
		}
	}
	if ( u == v ) return u;

	for ( int i = 20; i >= 0; i-- ){
		if ( pa[i][u] != pa[i][v] ){
			u = pa[i][u];
			v = pa[i][v];
		}
	}
	return pa[0][u];
}

LL Dist( int u, int v ){
	int lca = LCA(u,v);
	return Depth[u] + Depth[v] - 2 * 1LL * Depth[lca];
}

LL solve( int u, int p ){
	LL ans = 0;
	for ( int v : E[u] ){
		if ( v != p ) ans += solve(v,u);
	}
	if ( !mark[u] ){
		if ( Dist(st,u) > Dist(ed,u) ){
			ans += Dist(st,u);
			idx++;
			A[idx] = st;
			B[idx] = u;
			C[idx] = u;
		} else {
			ans += Dist(ed,u);
			idx++;
			A[idx] = ed;
			B[idx] = u;
			C[idx] = u;
		}
	}
	return ans;
}

int main(){

	memset(pa,-1,sizeof(pa));
	scanf("%d",&n);
	for ( int i = 0; i < n-1; i++ ){
		int u , v;
		scanf("%d%d",&u,&v);
		E[u].push_back(v);
		E[v].push_back(u);
	}
	dfs(1,-1,0);
	findDiameter();

	LL ans = 0;

	for ( int i = 1; i <= n; i++ ){
		if ( mark[i] ){
			for ( int v : E[i] ){
				if ( !mark[v] ){
					ans += solve(v,i);
				}
			}
		}
	}

	int id = ed;
	while ( id != st ){
		ans += dist[id];
		idx++;
		A[idx] = id;
		B[idx] = st;
		C[idx] = id;
		id = pi[id];
	}

	printf("%lld\n",ans);
	for ( int i = 1; i < n; i++ ){
		printf("%d %d %d\n",A[i], B[i], C[i]);
	}
	return 0;
}


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

int n;
vector < int > E[200005];
int dist[200005],pi[200005];
int st , ed;
int mark[200005];
int pa[22][200005];
int Depth[200005];
queue < int > q;
int A[200005], B[200005], C[200005];
int idx = 0;

void dfs( int u , int p, int d ){
	pa[0][u] = p;
	Depth[u] = d;
	for ( int i = 1; i < 21; i++ ){
		if ( pa[i-1][u] != -1 ) pa[i][u] = pa[i-1][pa[i-1][u]];
	}
	for ( int v : E[u] ){
		if ( v != p ) dfs(v,u,d+1);
	}
}

void findDiameter(){
	memset(dist,-1,sizeof(dist));
	dist[1] = 0;
	q.push(1);
	int far = 1;
	while ( !q.empty() ){
		int u = q.front();
		q.pop();
		far = u;
		for ( int v : E[u] ){
			if ( dist[v] == -1 ){
				dist[v] = dist[u] + 1;
				q.push(v);
			}
		}
	}
	memset(dist,-1,sizeof(dist));
	memset(pi,-1,sizeof(pi));
	st = far;
	dist[st] = 0;
	q.push(st);
	while ( !q.empty() ){
		int u = q.front();
		q.pop();
		far = u;
		for ( int v : E[u] ){
			if ( dist[v] == -1 ){
				dist[v] = dist[u] + 1;
				q.push(v);
				pi[v] = u;
			}
		}
	}

	ed = far;
	int bt = far;
	while ( bt != -1 ){
		mark[bt] = true;
		bt = pi[bt];
	}
}

int LCA( int u , int v ){
	if ( Depth[u] < Depth[v] ) swap(u,v);
	int diff = Depth[u] - Depth[v];
	for ( int i = 20; i >= 0; i-- ){
		if ( (diff>>i) & 1 ){
			u = pa[i][u];
		}
	}
	if ( u == v ) return u;

	for ( int i = 20; i >= 0; i-- ){
		if ( pa[i][u] != pa[i][v] ){
			u = pa[i][u];
			v = pa[i][v];
		}
	}
	return pa[0][u];
}

LL Dist( int u, int v ){
	int lca = LCA(u,v);
	return Depth[u] + Depth[v] - 2 * 1LL * Depth[lca];
}

LL solve( int u, int p ){
	LL ans = 0;
	for ( int v : E[u] ){
		if ( v != p ) ans += solve(v,u);
	}
	if ( !mark[u] ){
		if ( Dist(st,u) > Dist(ed,u) ){
			ans += Dist(st,u);
			idx++;
			A[idx] = st;
			B[idx] = u;
			C[idx] = u;
		} else {
			ans += Dist(ed,u);
			idx++;
			A[idx] = ed;
			B[idx] = u;
			C[idx] = u;
		}
	}
	return ans;
}

int main(){

	memset(pa,-1,sizeof(pa));
	scanf("%d",&n);
	for ( int i = 0; i < n-1; i++ ){
		int u , v;
		scanf("%d%d",&u,&v);
		E[u].push_back(v);
		E[v].push_back(u);
	}
	dfs(1,-1,0);
	findDiameter();

	LL ans = solve(1,-1);
	int id = ed;
	while ( id != st ){
		ans += dist[id];
		idx++;
		A[idx] = id;
		B[idx] = st;
		C[idx] = id;
		id = pi[id];
	}

	printf("%lld\n",ans);
	for ( int i = 1; i < n; i++ ){
		printf("%d %d %d\n",A[i], B[i], C[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].se << nl;
	}
}

int main() {
    setIO("");

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