Problem:
C: 同値命題

問題

$N$ 個の命題があり, それぞれ $1, 2, \cdots,N$ という名前がついている.

また, 命題に関する情報が $M$ 個与えられる. $i$ 番目の情報は「$a_i$ $b_i$」という形式で与えられ, これは $a_i$ ならば $b_i$ であることを表す.（「ならば」は論理包含であり、推移律が成り立つ）

各命題 $i$ に対して $i$ と同値な命題を全て昇順に出力せよ.

ただし命題 $i$ と命題 $i$ は常に同値である.

命題 $X$ と命題 $Y$ が同値とは,「$X$ ならば $Y$」かつ「$Y$ ならば $X$」のことである.

制約

入力値は全て整数である.

$ 2 \leq N \leq 300$

$ 1 \leq M \leq N(N - 1)$

$ a_i \neq b_i $

$1 \leq a_i, b_i \leq N $

入力形式

入力は以下の形式で与えられる.

$N\ M$

$a_1\ b_1$

$a_2\ b_2$

$\vdots$

$a_M\ b_M$

出力

$i$ 行目には命題 $i$ と同値である命題を昇順に空白区切りですべて出力せよ. また, 各行の末尾に改行を出力せよ.

サンプル

サンプル入力 1

5 2
1 2
2 1

サンプル出力 1

1 2
1 2
3
4
5

サンプル入力 2

3 3
1 2
2 3
3 1

サンプル出力 2

1 2 3
1 2 3
1 2 3

サンプル入力 3

6 7
1 2
1 3
2 6
3 4
4 5
5 3
6 2

サンプル出力 3

1
2 6
3 4 5
3 4 5
3 4 5
2 6

Solution in C (judge verdict: Accepted)

#include <stdio.h>

#define INF 999999999

int asumikana[512][512];

int main(void) {
	int N, M;
	int i, j, k;
	if (scanf("%d%d", &N, &M) != 2) return 1;
	for (i = 1; i <= N; i++) {
		for (j = 1; j <= N; j++) {
			asumikana[i][j] = INF;
		}
		asumikana[i][i] = 0;
	}
	for (i = 0; i < M; i++) {
		int a, b;
		if (scanf("%d%d", &a, &b) != 2) return 1;
		asumikana[a][b] = 1;
	}
	for (k = 1; k <= N; k++) {
		for (i = 1; i <= N; i++) {
			for (j = 1; j <= N; j++) {
				if (asumikana[i][j] > asumikana[i][k] + asumikana[k][j]) {
					asumikana[i][j] = asumikana[i][k] + asumikana[k][j];
				}
			}
		}
	}
	for (i = 1; i <= N; i++) {
		int isFirst = 1;
		for (j = 1; j <= N; j++) {
			if (asumikana[i][j] < INF && asumikana[j][i] < INF) {
				if (!isFirst) putchar(' ');
				printf("%d", j);
				isFirst = 0;
			}
		}
		putchar('\n');
	}
	return 0;
}