/*
  Copyright 2011,2015 Marek "p2004a" Rusinowski
  Computing strongly connected component, Kosaraju's algorithm
*/
#include <cstdio>
#include <vector>
#include <algorithm>

#define MAXN 1000000

std::vector<int> edges[MAXN];
std::vector<int> edges_t[MAXN];
int postorder[MAXN];
bool visited[MAXN];

void compute_postorder(int v, int &num) {
  visited[v] = true;
  for (int u: edges[v]) {
    if (!visited[u]) {
      compute_postorder(u, num);
    }
  }
  postorder[num++] = v;
}

void compute_scc(int v) {
  visited[v] = true;
  printf("%d ", v + 1);
  for (int u: edges_t[v]) {
    if (!visited[u]) {
      compute_scc(u);
    } 
  }
}

int main() {
  int n, m, a, b;
  scanf("%d %d", &n, &m);
  for (int i = 0; i < m; ++i) {
    scanf("%d %d", &a, &b);
    edges[--a].push_back(--b);
    edges_t[b].push_back(a);
  }
  int num = 0;
  for (int i = 0; i < n; ++i) {
    if (!visited[i]) {
      compute_postorder(i, num);
    }
  }
  std::fill(visited, visited + n, false);
  num = 0;
  for (int i = n - 1; i >= 0; --i) {
    if (!visited[postorder[i]]) {
      printf("%d: ", ++num);
      compute_scc(postorder[i]);
      printf("\n");
    }
  }
  return 0;
}