import java.io.*;
import java.util.*;
public class Solution
implements Runnable {
class DSU{
int[] arr;
DSU(int n) {
arr = new int[n];
for(int i=0;i<n;++i)
arr[i]=i;
}
int get(int v){
if(arr[v]==v)
return v;
return arr[v]=get(arr[v]);
}
void union(int a,int b){
arr[get(a)]=get(b);
}
}
class Edge{
int a,b;
Edge(int a, int b) {
this.a = a;
this.b = b;
}
}
int n=nextInt(),m=nextInt();
Edge[] edges = new Edge[m];
int[] deg = new int[n];
boolean[] is_useful = new boolean[n];
for(int i=0;i<m;++i){
edges[i] = new Edge(nextInt()-1,nextInt()-1);
++deg[edges[i].a];
++deg[edges[i].b];
}
int minIndex = 0;
for(int i=0;i<n;++i){
if(deg[i]<deg[minIndex]){
minIndex = i;
}
}
ArrayList<Integer> useful = new ArrayList<Integer>();
useful.add(minIndex);
for(Edge edge : edges){
if(edge.b == minIndex){
int tmp = edge.a;
edge.a=edge.b;
edge.b=tmp;
}
if(edge.a == minIndex){
is_useful[edge.b] = true;
useful.add(edge.b);
}
}
for(int i=0;i<useful.size();++i)
ht.put(useful.get(i),i);
int[] toUnUse = new int[useful.size()];
boolean [][] graph = new boolean[useful.size()][useful.size()];
for(Edge edge : edges){
if(is_useful[edge.a] && is_useful[edge.b]){
graph[ht.get(edge.a)][ht.get(edge.b)] = true;
}
else if(is_useful[edge.a]){
++toUnUse[ht.get(edge.a)];
}
else if(is_useful[edge.b]){
++toUnUse[ht.get(edge.b)];
}
}
for(int i=0;i<useful.size();++i){
if(toUnUse[i] == n-useful.size() + 1){
graph[i][ht.get(minIndex)] = true;
}
}
DSU dsu = new DSU(n);
for(int i=0;i<useful.size();++i)
for(int j=0;j<useful.size();++j)
if(!graph[i][j] && !graph[j][i])
dsu.union(i,j);
ArrayList
<Integer
>[] anses
= new ArrayList[useful.
size()]; for(int i=0;i<useful.size();++i){
anses[i] = new ArrayList<Integer>();
}
for(int i=0;i<n;++i){
anses[dsu.get(ht.get(is_useful[i]?i : minIndex))].add(i);
}
int empty = 0;
for(int i=0;i<useful.size();++i)
if(anses[i].isEmpty())
++empty;
out.println(useful.size() - empty);
for(int i=0;i<useful.size();++i){
if(!anses[i].isEmpty()){
out.print(anses[i].size());
out.print(" "+(j+1));
}
out.println();
}
}
}
public static void main
(String[] args
) { new Solution().run();
}
public void run() {
try {
solve();
out.println("IOException:");
out.println(e.getStackTrace());
}
out.flush();
}
while (st == null || !st.hasMoreTokens()) {
}
return st.nextToken();
}
return Integer.
parseInt(nextString
()); }
return Double.
parseDouble(nextString
()); }
return Long.
parseLong(nextString
()); }
}