// java 声明集合数组后还要再循环new一遍
// 思路和视频一样
import java.util.*;
public class Main{
class Graph{
List<List<Integer>> table;
List<Integer> tops;
int[] deg;
Queue<Integer> queue;
int vers;
Graph(int n) {
table = new ArrayList<>();
deg = new int[n];
for (int i = 0 ; i < n ; i++) table.add(new ArrayList<>());
vers = n;
queue = new LinkedList<>();
tops = new ArrayList<>();
}
void add(int x, int y){
table.get(x).add(y);
deg[y]++;
}
List<Integer> topSort(){
queue.clear();
for (int i = 0; i < vers ; i++){
if (deg[i] == 0) queue.add(i);
}
while (!queue.isEmpty()){
int head = queue.poll();
tops.add(head);
List<Integer> edges = table.get(head);
for (int i = 0 ;i < edges.size(); i++){
int end = edges.get(i);
if (--deg[end] == 0) queue.add(end);
}
}
return tops;
}
}
void run(){
int n = jin.nextInt();
int m = jin.nextInt();
Graph graph = new Graph(n);
for (int i = 0 ; i < m ; i++){
int x = jin.nextInt();
int y = jin.nextInt();
graph.add(x-1, y-1);
}
graph.topSort();
solve(graph, n );
}
void solve(Graph graph, int n){
BitSet[] sets = new BitSet[n];
for (int i = 0 ; i < n ; i ++) sets[i] = new BitSet();
for (int i = graph.tops.size() -1 ; i >= 0 ; i--){
int p = graph.tops.get(i);
var edges = graph.table.get(p);
sets[p].set(p);
for (int j = 0 ; j < edges.size() ; j++){
int end = edges.get(j);
sets[p].or(sets[end]);
}
}
for (int i = 0 ;i < graph.tops.size(); i ++){
System.out.println(sets[i].cardinality());
}
}
private Scanner jin = new Scanner(System.in);
public static void main(String[] args) throws Exception {new Main().run();}
}