Problem:
Score : 500 points

Problem Statement

There is a rooted tree (see Notes) with N vertices numbered 1 to N.
Each of the vertices, except the root, has a directed edge coming from its parent.
Note that the root may not be Vertex 1.

Takahashi has added M new directed edges to this graph.
Each of these M edges, u \rightarrow v, extends from some vertex u to its descendant v.

You are given the directed graph with N vertices and N-1+M edges after Takahashi added edges.
More specifically, you are given N-1+M pairs of integers, (A_1, B_1), ..., (A_{N-1+M}, B_{N-1+M}), which represent that the i-th edge extends from Vertex A_i to Vertex B_i.

Restore the original rooted tree.

Notes

For "tree" and other related terms in graph theory, see the article in Wikipedia, for example.

Constraints

3 \leq N

1 \leq M

N + M \leq 10^5

1 \leq A_i, B_i \leq N

A_i \neq B_i

If i \neq j, (A_i, B_i) \neq (A_j, B_j).

The graph in input can be obtained by adding M edges satisfying the condition in the problem statement to a rooted tree with N vertices.

Input

Input is given from Standard Input in the following format:

N M
A_1 B_1
:
A_{N-1+M} B_{N-1+M}

Output

Print N lines.
In the i-th line, print 0 if Vertex i is the root of the original tree, and otherwise print the integer representing the parent of Vertex i in the original tree.

Note that it can be shown that the original tree is uniquely determined.

Sample Input 1

3 1
1 2
1 3
2 3

Sample Output 1

0
1
2

The graph in this input is shown below:

It can be seen that this graph is obtained by adding the edge 1 \rightarrow 3 to the rooted tree 1 \rightarrow 2 \rightarrow 3.

Sample Input 2

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

Sample Output 2

6
4
2
0
6
2

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

//khodaya khodet komak kon
#include <bits/stdc++.h>

#define F first
#define S second
#define pb push_back
#define all(x) x.begin(), x.end()
#pragma GCC optimise ("ofast")
#pragma GCC optimise("unroll-loops")

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

const int N = 100000 + 10;
const ll MOD = 1000000000 + 7;
const ll INF = 1000000000000000000;
const ll LOG = 25;


bool M[N], mark[N];
int n, m, inv[N], par[N], p[N], IN[N], ans[N];
vector<int> G[N], ft, g[N];

int getpar(int v){
	return (par[v] == v ? v : par[v] = getpar(par[v]));
}

void merge(int v, int u){
	v = getpar(v), u = getpar(u);
	if (v == u) return;
	par[v] = u;
}

void DFS(int v, int p = 0){
	M[v] = 1;
	for (auto u:G[v]){
		if (!M[u]) DFS(u, v);
	}
	ft.pb(v);
}

bool cmp(int x, int y){
	return (inv[x] < inv[y]);
}


int32_t main(){
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= n; i++) par[i] = i;
	for (int i = 1; i <= n + m - 1; i++){
		int v, u;
		cin >> v >> u;
		G[v].pb(u);
		IN[u] ++;
	}
	int root;
	for (int i = 1; i <= n; i++){
		if (IN[i] == 0){
			root = i; 
		}
	}
	DFS(root);
	reverse(all(ft));
	//for (auto u:ft) cout << u << ' ';
	//cout << '\n';
	for (int i = 0; i < ft.size(); i++){
		inv[ft[i]] = i;
	}
	for (int i = 0; i < ft.size(); i++){
		sort(all(G[ft[i]]), cmp);
	}
	for (int i = ft.size() - 1; i >= 0; i--){
		for (auto u:G[ft[i]]){
		//	cout << i << ' ' << u << ' ' << getpar(u) << '\n';
			if (!mark[getpar(u)]){
				//cout << ft[i] << ' ' << u << '\n';
				mark[getpar(u)] = 1;
				ans[u] = ft[i];
			}
		}
		for (auto u:G[ft[i]]){
			mark[getpar(u)] = 0;
			merge(ft[i], u);
		}
	}
	for (int i = 1; i <= n; i++) cout << ans[i] << '\n';




	return 0;
}