#include <bits/stdc++.h>
using namespace std;

bool used[310];
int scc[310],k;
vector<int> G[310],rev[310],vs;

void add_edge(int from,int to){
	G[from].push_back(to);
	rev[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){
	used[v] = true;
	scc[v] = k;
	for(int to : rev[v]){
		if(!used[to]) rdfs(to);
	}
}

int n,m;

void build(){
	for(int i = 0;i < n;i++) used[i] = false;
	for(int i = 0;i < n;i++){
		if(!used[i]) dfs(i);
	}
	for(int i = 0;i < n;i++) used[i] = false;
	k = 0;
	for(int i = n - 1;i >= 0;i--){
		if(!used[vs[i]]){
			rdfs(vs[i]);
			k++;
		}
	}
}

signed main(){
	cin >> n >> m;
	for(int i = 0;i < m;i++){
		int a,b;
		cin >> a >> b; a--;b--;
		add_edge(a,b);
	}
	build();
	for(int i = 0;i < n;i++){
		bool isFirst = true;
		for(int j = 0;j < n;j++){
			if(scc[i] == scc[j]){
				cout << (isFirst ? "" : " ") << j + 1;
				isFirst = false;
			}
		}
		cout << endl;
	}
}

### Prompt

Please formulate a Cpp solution to 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 <bits/stdc++.h>
using namespace std;

bool used[310];
int scc[310],k;
vector<int> G[310],rev[310],vs;

void add_edge(int from,int to){
	G[from].push_back(to);
	rev[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){
	used[v] = true;
	scc[v] = k;
	for(int to : rev[v]){
		if(!used[to]) rdfs(to);
	}
}

int n,m;

void build(){
	for(int i = 0;i < n;i++) used[i] = false;
	for(int i = 0;i < n;i++){
		if(!used[i]) dfs(i);
	}
	for(int i = 0;i < n;i++) used[i] = false;
	k = 0;
	for(int i = n - 1;i >= 0;i--){
		if(!used[vs[i]]){
			rdfs(vs[i]);
			k++;
		}
	}
}

signed main(){
	cin >> n >> m;
	for(int i = 0;i < m;i++){
		int a,b;
		cin >> a >> b; a--;b--;
		add_edge(a,b);
	}
	build();
	for(int i = 0;i < n;i++){
		bool isFirst = true;
		for(int j = 0;j < n;j++){
			if(scc[i] == scc[j]){
				cout << (isFirst ? "" : " ") << j + 1;
				isFirst = false;
			}
		}
		cout << endl;
	}
}

```