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)

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdint.h>
#include <tuple>
#include <utility>
#include <vector>

using namespace std;

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-12;
static const double PI = acos(-1.0);
static const ll MOD = 1000000007;

#define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define ALL(a) (a).begin(), (a).end()
#define DEBUG(x) cout << #x << ": " << x << endl

typedef ll Node; // Node番号

class TopologicalSort {
public:
  void Init(ll size) {
    V = size;
    graph.resize(size);
    indegree.resize(size);
  }

  void AddEdge(Node from, Node to) {
    graph[from].push_back(Edge{to});
    indegree[to]++;
  }

  vector<Node> Sort() {
    stack<Node> st; //入次数が0の頂点の集合
    REP(i, V) {
      if (indegree[i] == 0) {
        st.push(i);
      }
    }
    vector<Node> ans;
    while (st.size()) {
      Node i = st.top();
      st.pop();
      ans.push_back(i);
      for (const auto &j : graph[i]) {
        indegree[j.to]--;
        if (indegree[j.to] == 0)
          st.push(j.to);
      }
    }
    return ans;
  }

private:
  ll V;
  struct Edge {
    Node to;
  };
  vector<vector<Edge>> graph;
  vector<ll> indegree;
};

map<ll, ll> node_to_order;

bool comp(const pair<ll, ll> &l, const pair<ll, ll> &r) {
  if (l.second < r.second) {
    return true;
  } else if (l.second > r.second) {
    return false;
  } else {
    return node_to_order[l.first] > node_to_order[r.first];
  }
}

void solve(long long N, long long M, std::vector<long long> A,
           std::vector<long long> B) {
  TopologicalSort t;
  t.Init(N);
  REP(i, A.size()) {
    t.AddEdge(A[i] - 1, B[i] - 1);
  }
  auto ans = t.Sort();
  for (int i : ans) {
    node_to_order[ans[i]] = i;
  }
  vector<pair<ll, ll>> C(A.size());
  REP(i, A.size()) {
    C[i].first = A[i] - 1;
    C[i].second = B[i] - 1;
  }
  sort(ALL(C), comp);
  vector<ll> parent(N, 0);
  ll prev = -1;
  REP(i, C.size()) {
    if (prev == C[i].second) {
      C[i].first = -1;
    } else {
      parent[C[i].second] = C[i].first + 1;
    }
    prev = C[i].second;
  }
  REP(i, N) { std::cout << parent[i] << std::endl; }
}

int main() {
  long long N;
  scanf("%lld", &N);
  long long M;
  scanf("%lld", &M);
  std::vector<long long> A(N - 1 + M);
  std::vector<long long> B(N - 1 + M);
  for (int i = 0; i < N - 1 + M; i++) {
    scanf("%lld", &A[i]);
    scanf("%lld", &B[i]);
  }
  solve(N, M, std::move(A), std::move(B));
  return 0;
}