module main; // https://kmjp.hatenablog.jp/entry/2015/07/13/0930 より import std; // 多次元配列をある値で埋める void fill(A, T)(ref A a, T value) if (isArray!A) { alias E = ElementType!A; static if (isArray!E) { foreach (ref e; a) fill(e, value); } else { a[] = value; } } int N, M; alias P = Tuple!(int, int); P[][] V; long[][] memo; void dfs(int cur) { if (memo[cur][0] >= 0) return; fill(memo[cur], 0); if (V[cur].empty) { memo[cur][cur] = 1; return; } foreach (e; V[cur]) { dfs(e[0]); foreach (j; 0 .. N) memo[cur][j] += e[1] * memo[e[0]][j]; } } void main() { N = readln.chomp.to!int; M = readln.chomp.to!int; V = new P[][](N + 1); foreach (_; 0 .. M) { int p, q, r; readln.chomp.formattedRead("%d %d %d", p, q, r); V[r - 1] ~= P(p - 1, q); } memo = new long[][](N + 1, N + 1); fill(memo, -1); dfs(N - 1); foreach (i; 0 .. N - 1) writeln(memo[N - 1][i]); }