#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define all(v) v.begin(), v.end()
const ll INF = 4e18;
void fileio() {
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
}
int n, m;
vector<vector<int>> adj;
vector<int> vis;
int dx[]={-1 ,1 ,0 , 0};
int dy[]={0 , 0 ,-1 ,1};
/* =========================
DFS
========================= */
void dfs(int u) {
vis[u] = 1;
for (int v : adj[u]) {
if (!vis[v]) {
dfs(v);
}
}
}
/* =========================
BFS
Shortest path in unweighted graph
========================= */
vector<int> bfs(int src) {
vector<int> dist(n + 1, -1);
queue<int> q;
dist[src] = 0;
q.push(src);
while (!q.empty()) {
int u = q.front();
q.pop();
for (int v : adj[u]) {
if (dist[v] == -1) {
dist[v] = dist[u] + 1;
q.push(v);
}
}
}
return dist;
}
/* =========================
Connected Components
Undirected graph
========================= */
int count_components() {
vis.assign(n + 1, 0);
int components = 0;
for (int i = 1; i <= n; i++) {
if (!vis[i]) {
components++;
dfs(i);
}
}
return components;
}
/* =========================
Cycle Detection
Undirected graph
========================= */
bool dfs_cycle_undirected(int u, int parent) {
vis[u] = 1;
for (int v : adj[u]) {
if (!vis[v]) {
if (dfs_cycle_undirected(v, u)) {
return true;
}
} else if (v != parent) {
return true;
}
}
return false;
}
bool has_cycle_undirected() {
vis.assign(n + 1, 0);
for (int i = 1; i <= n; i++) {
if (!vis[i]) {
if (dfs_cycle_undirected(i, -1)) {
return true;
}
}
}
return false;
}
/* =========================
Cycle Detection
Directed graph
0 = unvisited
1 = currently visiting
2 = finished
========================= */
vector<int> color;
bool dfs_cycle_directed(int u) {
color[u] = 1;
for (int v : adj[u]) {
if (color[v] == 0) {
if (dfs_cycle_directed(v)) {
return true;
}
} else if (color[v] == 1) {
return true;
}
}
color[u] = 2;
return false;
}
bool has_cycle_directed() {
color.assign(n + 1, 0);
for (int i = 1; i <= n; i++) {
if (color[i] == 0) {
if (dfs_cycle_directed(i)) {
return true;
}
}
}
return false;
}
/* =========================
Topological Sort DFS
Directed Acyclic Graph only
Not lexicographically smallest
========================= */
vector<int> topo;
bool cycle;
void dfs_topo(int u) {
color[u] = 1;
for (int v : adj[u]) {
if (color[v] == 0) {
dfs_topo(v);
} else if (color[v] == 1) {
cycle = true;
}
}
color[u] = 2;
topo.push_back(u);
}
vector<int> topo_sort_dfs() {
color.assign(n + 1, 0);
topo.clear();
cycle = false;
for (int i = 1; i <= n; i++) {
if (color[i] == 0) {
dfs_topo(i);
}
}
if (cycle) {
return {};
}
reverse(all(topo));
return topo;
}
/* =========================
Topological Sort Kahn
Lexicographically smallest
Use this for SPOJ TOPOSORT
========================= */
vector<int> topo_sort_kahn_lexicographical() {
vector<int> indeg(n + 1, 0);
for (int u = 1; u <= n; u++) {
for (int v : adj[u]) {
indeg[v]++;
}
}
priority_queue<int, vector<int>, greater<int>> pq;
for (int i = 1; i <= n; i++) {
if (indeg[i] == 0) {
pq.push(i);
}
}
vector<int> ans;
while (!pq.empty()) {
int u = pq.top();
pq.pop();
ans.push_back(u);
for (int v : adj[u]) {
indeg[v]--;
if (indeg[v] == 0) {
pq.push(v);
}
}
}
if ((int)ans.size() != n) {
return {};
}
return ans;
}
/* =========================
Bipartite Check
Undirected graph
========================= */
bool is_bipartite() {
vector<int> color_bip(n + 1, -1);
for (int start = 1; start <= n; start++) {
if (color_bip[start] != -1) continue;
queue<int> q;
q.push(start);
color_bip[start] = 0;
while (!q.empty()) {
int u = q.front();
q.pop();
for (int v : adj[u]) {
if (color_bip[v] == -1) {
color_bip[v] = color_bip[u] ^ 1;
q.push(v);
} else if (color_bip[v] == color_bip[u]) {
return false;
}
}
}
}
return true;
}
/* =========================
Dijkstra
Weighted graph
No negative weights
========================= */
vector<vector<pair<int, ll>>> wadj;
vector<ll> dijkstra(int src) {
vector<ll> dist(n + 1, INF);
priority_queue<
pair<ll, int>,
vector<pair<ll, int>>,
greater<pair<ll, int>>
> pq;
dist[src] = 0;
pq.push({0, src});
while (!pq.empty()) {
auto [d, u] = pq.top();
pq.pop();
if (d != dist[u]) continue;
for (auto [v, w] : wadj[u]) {
if (dist[u] + w < dist[v]) {
dist[v] = dist[u] + w;
pq.push({dist[v], v});
}
}
}
return dist;
}
/* =========================
Main solve
========================= */
void solve() {
cin >> n >> m;
adj.assign(n + 1, vector<int>());
vis.assign(n + 1, 0);
for (int i = 0; i < m; i++) {
int u, v;
cin >> u >> v;
// Undirected:
// adj[u].push_back(v);
// adj[v].push_back(u);
// Directed:
adj[u].push_back(v);
}
vector<int> ans = topo_sort_kahn_lexicographical();
if (ans.empty()) {
cout << "Sandro fails.\n";
return;
}
for (int x : ans) {
cout << x << " ";
}
cout << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
//fileio();
int t = 1;
// cin >> t;
while (t--) {
solve();
}
return 0;
}