#include <cstdio>
#include <cstdint>
#include <vector>
#include <algorithm>
#include <utility>
#include <numeric>

constexpr intmax_t  operator ""_jd(unsigned long long n) { return n; }
constexpr uintmax_t operator ""_ju(unsigned long long n) { return n; }
constexpr size_t    operator ""_zu(unsigned long long n) { return n; }
// constexpr ptrdiff_t operator ""_td(unsigned long long n) { return n; }

template <typename F>
class fix_point: F {
public:
  explicit constexpr fix_point(F&& f) noexcept: F(std::forward<F>(f)) {}

  template <typename... Args>
  constexpr decltype(auto) operator ()(Args&&... args) const {
    return F::operator ()(*this, std::forward<Args>(args)...);
  }
};

template <typename F>
static inline constexpr decltype(auto) make_fix_point(F&& f) noexcept {
  return fix_point<F>{std::forward<F>(f)};
}

template <typename Weight>
struct edge {
  using value_type = Weight;
  size_t src, dst;
  value_type cost;

  edge(size_t src, size_t dst, value_type cost = 1):
    src(src), dst(dst), cost(cost)
  {}

  bool operator <(edge<value_type> const& rhs) const {
    if (cost != rhs.cost) return cost < rhs.cost;
    if (src != rhs.src) return src < rhs.src;
    return dst < rhs.dst;
  }
};

template <typename Weight>
struct graph: public std::vector<std::vector<edge<Weight>>> {
  using value_type = Weight;
  graph(size_t n): std::vector<std::vector<edge<value_type>>>(n) {}

  void connect_to(size_t src, size_t dst, value_type cost = 1) {
    (*this)[src].emplace_back(src, dst, cost);
  }

  void connect_with(size_t src, size_t dst, value_type cost = 1) {
    connect_to(src, dst, cost);
    connect_to(dst, src, cost);
  }
};

template <class Weight>
std::vector<size_t> strongly_connected_components(const graph<Weight>& g) {
  size_t n = g.size();
  graph<int> rev(n);
  for (const auto& v: g)
    for (const auto& e: v)
      rev.connect_to(e.dst, e.src);

  std::vector<bool> used(n);
  std::vector<size_t> vs;
  auto dfs = make_fix_point([&](auto f, size_t v) -> void {
      used[v] = true;
      for (size_t i = 0; i < g[v].size(); ++i)
        if (!used[g[v][i].dst]) f(g[v][i].dst);
      vs.push_back(v);
  });
  for (size_t i = 0; i < n; ++i)
    if (!used[i]) dfs(i);

  used.assign(n, false);
  std::vector<size_t> cmp(n);
  size_t num = 0;
  auto rdfs = make_fix_point([&](auto f, size_t v) -> void {
      used[v] = true;
      cmp[v] = num;
      for (size_t i = 0; i < rev[v].size(); ++i)
        if (!used[rev[v][i].dst]) f(rev[v][i].dst);
  });

  for (size_t i = vs.size(); i--;)
    if (!used[vs[i]]) {
      rdfs(vs[i]);
      ++num;
    }

  return cmp;
}

int main() {
  size_t n, m;
  scanf("%zu %zu", &n, &m);

  graph<int> g(n);
  for (size_t i = 0; i < m; ++i) {
    size_t a, b;
    scanf("%zu %zu", &a, &b);
    --a, --b;
    g.connect_to(a, b);
  }

  auto scc = strongly_connected_components(g);

  // for (size_t i = 0; i < n; ++i)
  //   fprintf(stderr, "%zu%c", scc[i], i+1<n? ' ': '\n');

  std::vector<std::vector<size_t>> h(n);
  for (size_t i = 0; i < n; ++i) {
    h[scc[i]].push_back(i);
  }

  for (size_t i = 0; i < n; ++i) {
    for (size_t j = 0; j < h[scc[i]].size(); ++j)
      printf("%zu%c", h[scc[i]][j]+1, j+1<h[scc[i]].size()? ' ': '\n');
  }
}



Measured memory_bytes: 9768