#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <numeric>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(x) ;
#else
#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

template <typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template <typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v) out << item << ", ";
  out << "\b\b}";
  return out;
}
#endif

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 200010

/* Strongly Connected Component */

/*
  1. dfsをして、戻るときに1から順に番号を付ける
  2. 数値が大きいノードから逆辺を使ってdfsをする。
  すでに訪れているノードには行かない。
  たどり着けるノードが同じ連結成分に属する。
*/

struct SCC{
  int n;
  vector<vector<int> > G, rG;
  vector<int> vs, cmp;
  vector<bool> used;

  SCC(int n):n(n), G(n), rG(n), cmp(n){}

  void add_edge(int from, int to){
    G[from].push_back(to);
    rG[to].push_back(from);
  }

  void dfs(int v){
    used[v] = true;
    for(int to : G[v])
      if(!used[to]) dfs(to);
    vs.push_back(v);
  }

  void rdfs(int v, int k){
    used[v] = true;
    cmp[v] = k;
    for(int to : rG[v])
      if(!used[to]) rdfs(to, k);
  }

  int solve(){
    used.assign(n, false);
    vs.clear();
    for(int i=0; i<n; i++)
      if(!used[i]) dfs(i);
    used.assign(n, false);
    int k = 0;
    for(int i=(int)vs.size()-1; i>=0; i--)
      if(!used[vs[i]]) rdfs(vs[i], k++);
    return k; //強連結成分数
  }

  //属する強連結成分番号(トポロジカル順)
  int operator[](int k) const {
    return cmp[k];
  }
};

int main(){
  int N, M;

  cin >> N >> M;

  vector<int> ans;
  SCC scc(N);

  for(int i=0; i<M; i++) {
    int a, b;
    cin >> a >> b;
    scc.add_edge(a-1, b-1);
  }

  scc.solve();

  for(int i=0; i<N; i++) {
    bool first = true;

    for(int j=0; j<N; j++) {
      if (scc[i] == scc[j]) {
        if (!first) printf(" ");
        printf("%d", j+1);
        first = false;
      }
    }

    puts("");
  }


  return 0;
}


### Prompt

Create a solution in Cpp for the following problem:

problem

There are $ N $ propositions, named $ 1, 2, \ cdots, N $, respectively. Also, $ M $ information about the propositions is given. The $ i $ th information is "$ a_i $$". Given in the form "b_i $", which means that $ a_i $ is $ b_i $. ("If" is a logical conditional and the transition law holds.) $ For each proposition $ i $ Output all propositions that have the same value as i $ in ascending order. However, proposition $ i $ and proposition $ i $ are always the same value. Proposition $ X $ and proposition $ Y $ have the same value as "$ if $ X $". It means "Y $" and "$ X $ if $ Y $".



output

On the $ i $ line, output all propositions that have the same value as the proposition $ i $, separated by blanks in ascending order. Also, output a line break at the end of each line.

Example

Input

5 2
1 2
2 1


Output

1 2
1 2
3
4
5

### Response

```cpp
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <numeric>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(x) ;
#else
#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

template <typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template <typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v) out << item << ", ";
  out << "\b\b}";
  return out;
}
#endif

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 200010

/* Strongly Connected Component */

/*
  1. dfsをして、戻るときに1から順に番号を付ける
  2. 数値が大きいノードから逆辺を使ってdfsをする。
  すでに訪れているノードには行かない。
  たどり着けるノードが同じ連結成分に属する。
*/

struct SCC{
  int n;
  vector<vector<int> > G, rG;
  vector<int> vs, cmp;
  vector<bool> used;

  SCC(int n):n(n), G(n), rG(n), cmp(n){}

  void add_edge(int from, int to){
    G[from].push_back(to);
    rG[to].push_back(from);
  }

  void dfs(int v){
    used[v] = true;
    for(int to : G[v])
      if(!used[to]) dfs(to);
    vs.push_back(v);
  }

  void rdfs(int v, int k){
    used[v] = true;
    cmp[v] = k;
    for(int to : rG[v])
      if(!used[to]) rdfs(to, k);
  }

  int solve(){
    used.assign(n, false);
    vs.clear();
    for(int i=0; i<n; i++)
      if(!used[i]) dfs(i);
    used.assign(n, false);
    int k = 0;
    for(int i=(int)vs.size()-1; i>=0; i--)
      if(!used[vs[i]]) rdfs(vs[i], k++);
    return k; //強連結成分数
  }

  //属する強連結成分番号(トポロジカル順)
  int operator[](int k) const {
    return cmp[k];
  }
};

int main(){
  int N, M;

  cin >> N >> M;

  vector<int> ans;
  SCC scc(N);

  for(int i=0; i<M; i++) {
    int a, b;
    cin >> a >> b;
    scc.add_edge(a-1, b-1);
  }

  scc.solve();

  for(int i=0; i<N; i++) {
    bool first = true;

    for(int j=0; j<N; j++) {
      if (scc[i] == scc[j]) {
        if (!first) printf(" ");
        printf("%d", j+1);
        first = false;
      }
    }

    puts("");
  }


  return 0;
}


```