//反向建边+nv次dfs【从大到小】
#include <bits/stdc++.h>
using namespace std;
int nv,ne;
vector<int> v[100010];
int ans[100010];
void dfs(int root,int index){
if(ans[root]) return;//被访问过
ans[root]=index;
for(int i=0;i<v[root].size();i++)
dfs(v[root][i],index);//开头判断了,子结点不必再判断
}
int main(){
scanf("%d %d",&nv,&ne);
int t1,t2;
for(int i=0;i<ne;i++){
scanf("%d %d",&t1,&t2);
v[t2].push_back(t1);//反向建边
}
for(int i=nv;i>=1;i--) dfs(i,i);
//除非不被任何比自己index大的结点访问,不然最大就是自己的index
for(int i=1;i<=nv;i++){
printf("%s%d",i==1?"":" ",ans[i]);
}
return 0;
}
//nv次dfs
//90分,1个点超时
#include <bits/stdc++.h>
using namespace std;
int nv,ne;
vector<int> v[100010];
int visited_dfs[100010];
void dfs(int root,int & maxId,int index){
if(maxId==nv) return;
if(maxId<root) maxId=root;
visited_dfs[root]=index;//每次用index表示当前次访问,下一次dfs不必更新visited数组值
for(int i=0;i<v[root].size();i++){
if(visited_dfs[v[root][i]]!=index) dfs(v[root][i],maxId,index);
}
}
int main(){
scanf("%d %d",&nv,&ne);
int t1,t2;
for(int i=0;i<ne;i++){
scanf("%d %d",&t1,&t2);
v[t1].push_back(t2);
}
int maxId=0;
for(int i=1;i<=nv;i++){
dfs(i,maxId,i);
printf("%s%d",i==1?"":" ",maxId);
maxId=0;//为下次dfs初始化
}
return 0;
}