#include <iostream>
#include <iomanip>
#include <string>
#include <cmath>
#include <climits>
#include <algorithm>
#include <cassert>
#include <vector>
#include <array>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <stack>
#include <queue>
#include <numeric>
#define ALL(c) (c).begin(), (c).end()

using namespace std;
using ll = long long;
using pli = pair<ll, int>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pdi = pair<double, int>;
using pdd = pair<double, double>;

// Graph.h start--------------------------------------------
#pragma once

#include <vector>

using Weight = long long;

struct Vertex;
using Vertices = std::vector<Vertex *>;
struct Edge;
using Edges = std::vector<const Edge *>;

struct Vertex {
	const int id;
	Edges edges;
	Vertex(int id);
	void add_edge(const Edge *const p_e);
	void add_edge(const Edges &es);
};

struct Edge {
	Vertex *p_src, *p_dst;
	Weight weight;
	
	Edge(Vertex *p_src, Vertex *p_dst, Weight weight);
	Edge(const Edge &e);
	Edge& operator = (const Edge &de);
};

struct Graph {
	Vertices vertices;
	Edges edges;
	Graph(int nvertices);
	~Graph();
	void add_edge(Edge *p_edge);
	void add_edge(int edge_src, int edge_dst, Weight w);
	//void copy_vertex(int id_original, int id_copy);
};

//----------------------------------------------------------

using namespace std;

Vertex::Vertex(int id) : id(id) { }
void Vertex::add_edge(const Edge *const p_e) {
	edges.push_back(p_e);
}
void Vertex::add_edge(const Edges &es) {
	for (const auto &p_e : es) {
		add_edge(p_e);
	}
}

Edge::Edge(Vertex *p_src, Vertex *p_dst, Weight weight) : p_src(p_src), p_dst(p_dst), weight(weight) { }
Edge::Edge(const Edge &e) : Edge(e.p_src, e.p_dst, e.weight) {}
Edge& Edge::operator = (const Edge &e) {
	p_src = e.p_src;
	p_dst = e.p_dst;
	weight = e.weight;
	return *this;
}
bool operator < (const Edge &e1, const Edge &e2) {
	return e1.weight != e2.weight ? e1.weight > e2.weight : // !!INVERSE!!
		e1.p_src != e2.p_src ? e1.p_src->id < e2.p_src->id : e1.p_dst->id < e2.p_dst->id;
}

Graph::Graph(int nvertices) {
	for (int id = 0; id < nvertices; id++) {
		vertices.push_back(new Vertex(id));
	}
}
Graph::~Graph() {
	for (auto &p_vertex : vertices) {
		delete p_vertex;
	}
	for (auto &p_edge : edges) {
		delete p_edge;
	}
}
void Graph::add_edge(Edge *p_edge) {
	(*vertices[p_edge->p_src->id]).add_edge(p_edge);
	edges.push_back(p_edge);
}
void Graph::add_edge(int edge_src, int edge_dst, Weight w) {
	add_edge(new Edge(vertices[edge_src], vertices[edge_dst], w));
}
//void Graph::copy_vertex(int id_original, int id_copy) {
//	vertices[id_copy]->add_edge(vertices[id_original]->edges);
//}

// Graph.h end----------------------------------------------

// ShortPath.h start----------------------------------------

bool topologicalSort(const Graph &g, vector<int> &id_ordered);

//----------------------------------------------------------

bool visit(const Graph &g, int id, vector<int> &id_ordered, vector<int> &color) {
	if (color[id] == 2)
		return true;
	if (color[id] == 1)
		return false;
	color[id] = 1; //temporary
	for (const auto &e : g.vertices[id]->edges)
		if (!visit(g, e->p_dst->id, id_ordered, color))
			return false;
	color[id] = 2; //permanent
	id_ordered.push_back(id);
	return true;
}

bool topologicalSort(const Graph &g, vector<int> &id_ordered) {
	const size_t n = g.vertices.size();
	vector<int> color(n, 0);
	for (int id = 0; id < n; id++)
		if (color[id] == 0)
			if(!visit(g, id, id_ordered, color))
				return false;
	reverse(id_ordered.begin(), id_ordered.end());
	return true;
}

// ShortPath.h end----------------------------------------------

int N, M;
vector<int> A, B;

int main() {
	cin >> N >> M;
	for (int i = 0; i < N - 1 + M; i++) {
		int tmpa, tmpb;
		cin >> tmpa >> tmpb;
		A.push_back(tmpa - 1);
		B.push_back(tmpb - 1);
	}

	Graph g(N);
	for (int i = 0; i < N - 1 + M; i++)
	{
		g.add_edge(A[i], B[i], 0);
	}

	vector<int> id_ordered;
	topologicalSort(g, id_ordered);

	vector<int> ans(N, -1);
	for (int id = N - 1; id >= 0; id--)
	{
		for (const auto p_e : g.vertices[id_ordered[id]]->edges) {
			if (ans[p_e->p_dst->id] == -1) {
				ans[p_e->p_dst->id] = id_ordered[id];
			}
		}
	}

	for (size_t i = 0; i < N; i++)
	{
		cout << ans[i] + 1 << endl;
	}

	return 0;
}


Measured memory_bytes: 19696