#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N=2e5+10;
struct node{
int id,u,v;
};
node e[N];
int s[N],n,m;
void init(){
for(int i=1;i<=2e5;i++)
s[i]=i;
}
int find(int x){
return s[x]==x?x:s[x]=find(s[x]);
}
void merge(int x,int y)
{
int i=find(x),j=find(y);
if(i>j)//链式并查集,数值大的向小的合并
swap(i,j);
s[j]=i;
}
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
vector<node>p;
init();//不要忘记并查集的初始化
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>e[i].u>>e[i].v;
e[i].id=i;
if(find(e[i].u)==find(e[i].v))
p.push_back(e[i]);
else
merge(e[i].u,e[i].v);
}
vector<int>a;
for(int i=1;i<=n;i++){
if(find(i)!=1){
a.push_back(s[i]);
}
}
sort(a.begin(),a.end());
a.erase(unique(a.begin(),a.end()),a.end());//unique使用前要先排序
cout<<a.size()<<endl;
int t=a.size();/*a.size在下面的for循环中动态变化,需要提前保存该常数!!!*/
vector<bool>vis(N,0);
for(int i=0;i<t;i++){
int x=p[i].u,y=p[i].v;
int fa=find(x),id=p[i].id;
if(fa==1){
while(a.size()&&vis[a.back()])a.pop_back();
cout<<id<<' '<<x<<' '<<a.back()<<endl;
merge(1,a.back());
a.pop_back();
}
else{
cout<<id<<" "<<x<<' '<<1<<endl;
vis[fa]=1;
merge(fa,1);
}
}
}
#链式并查集 #
25/2/8