#include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define int ll
#define rep(i,n) for(int i=0;i<n;i++)
#define all(in) in.begin(), in.end()
constexpr int INF = (numeric_limits<int>::max() == INT_MAX ? (int)1e9 : (long long)1e18);
constexpr long double eps = 1e-6;
const string el = "\n";
template<class T, class S> void cmin(T &a, const S &b) { if (a > b)a = b; }
template<class T, class S> void cmax(T &a, const S &b) { if (a < b)a = b; }
template<typename Head, typename Value> auto vectors(const Head &head, const Value &v) { return vector<Value>(head, v); }
template<typename Head, typename... Tail> auto vectors(Head x, Tail... tail) { auto inner = vectors(tail...); return vector<decltype(inner)>(x, inner); }
using ld = long double;using pii = pair<int,int>;using piii = pair<int,pii>;
int W,H;
int dx[]={0,0,1,-1}, dy[]={1,-1,0,0};
bool valid(int x,int y){return (0<=x&&x<W)&&(0<=y&&y<H);}
void fast_io(){ios::sync_with_stdio(false); cin.tie(nullptr);}
int out(int a){cout << a << el; return 0;}
int out(string s = "NO"){cout << s << el; return 0;}
template <class T>
inline int out(vector<T>&v,string c = " "){
    for(int i = 0; i < v.size(); ++i){
        if(i) cout << c; cout << v[i];
    } cout << el;return 0;
}
template<typename T>
class StronglyConnectedComponents{
    vector<vector<T>>edge,rev_edge,compressed_edge,point_set;
    vector<int>order,vcomp,sort_order_vec;
    vector<bool>visit;
    int v_size = 0,compress_size = 0;
    void dfs(int v){
        visit[v] = true;
        for(auto nv : edge[v])
            if(not visit[nv]) dfs(nv);
        order.push_back(v);
    }
    void dfs_compress(int v){
        vcomp[v] = compress_size;
        for(auto nv : rev_edge[v])
            if(vcomp[nv] == -1) dfs_compress(nv);
    }
    void rev_edge_build(){
        for(int nv = 0; nv < edge.size(); ++nv)
            for(auto v : edge[nv])
                rev_edge[v].push_back(nv);
    }
    void popsort(){
        for(int v = 0; v < edge.size(); ++v)
            if(not visit[v]) dfs(v);
    }
    void compress_vertex(){
        for(auto itr = order.rbegin(); itr != order.rend();++itr ){
            auto v = *itr;
            if(vcomp[v] == -1){
                dfs_compress(v); compress_size++;
            }
        }
    }
    void construct_strcomp(){
        compress_vertex();
        //create compressed graph
        compressed_edge = vector<vector<T>>(compress_size);
        for(int frm = 0; frm < edge.size(); ++frm)
            for(auto to : edge[frm]){
                if(vcomp[frm] == vcomp[to])continue;
                compressed_edge[vcomp[frm]].push_back(vcomp[to]);
            }
    }
    void construct_point_set(){
        point_set = vector<vector<int>>(compress_size);
        for(int v = 0; v < vcomp.size(); ++v){
            point_set[vcomp[v]].push_back(v);
        }
    }
public:
    StronglyConnectedComponents(vector<vector<T>>&e)
    :v_size((int)e.size()),edge(e),order{},rev_edge(e.size()){};
    int operator [](int v){
        return sort_order_vec[v];
    }
    void build(){
        rev_edge_build();
        visit = vector<bool>(v_size,false);
        popsort();
        vcomp = vector<int>(v_size,-1);
        construct_strcomp();
        construct_point_set();
    }
    bool isSamePointSet(int v, int u){return vcomp[v] == vcomp[u];}
    int scc_size(){return compress_size;}
    vector<vector<int>> get_point_set(){
        return point_set;
    }
};
void dfs_popsort(int cv,int& idx,vector<vector<int>>&edge,
                 vector<bool>&visit,vector<int>&out){
    visit[cv] = true;
    for(auto nv : edge[cv]){
        if(not visit[nv])dfs_popsort(nv,idx,edge,visit,out);
    }
    out[idx--] = cv;
}
auto TopologicalSort(vector<vector<int>>&edge){
    int N = edge.size();
    vector<bool>v(N,false);
    vector<int>out(N,-1);
    int idx = N-1;
    for(int i = 0; i < v.size();i++){
        if(not v[i])dfs_popsort(i,idx,edge,v,out);
    }
    return out;
}
//inline void solve(){
//    int N,t; cin >> N >> t;
//    vector<vector<int>>edge(N),tmp(N),directed_edge(N);
//    vector<tuple<int,int,int>>tup;
//    vector<tuple<int,int>>ans;
//    rep(i,t){
//        int d,s,t; cin >> d >> s >> t;
//        --t;--s;
//        tup.emplace_back(d,s,t);
//        if(d == 1){
//            edge[s].push_back(t);
//            directed_edge[s].emplace_back(t);
//        } else {
//            edge[t].push_back(s);
//            edge[s].push_back(t);
//        }
//    }
//    StronglyConnectedComponents<int>SCC(directed_edge);
//    SCC.build();
//    vector<int>order(N,-1);
//    int id  = 0;
//    for( auto  v : TopologicalSort(directed_edge,-1)){
//        order[v] = id++;
//    }
//    if(SCC.scc_size() != N){
//        out("NO"); return;
//    }
//    out("YES");
//    for(auto [d,s,t] : tup){
//        if(d == 1){
//            ans.emplace_back(s,t);
//        } else {
//            if(order[s] < order[t])
//                ans.emplace_back(s,t);
//            else
//                ans.emplace_back(t,s);
//        }
//    }
//    for(auto[s,t] : ans)
//        cout << s + 1 << " " << t + 1 << endl;
//    return;
//}
void yebi(){
    int N,Q;
    cin >> N >> Q;
    vector<vector<int>>edge(N);
    rep(_,Q){
        int s,t; cin >> s >> t;
        edge[s].push_back(t);
    }
    vector<int>order;
    for(auto v : TopologicalSort(edge)){
        order.push_back(v);
    }
    out(order,"\n");
}
signed main(){
    fast_io();
    int Q = 1;
    //cin >> Q;
    yebi(); return 0;
    //while(Q--){solve();}
}


Measured memory_bytes: 3872