#include<bits/stdc++.h>
#define MAXN 10010
#define MAXM 50010
using namespace std;
struct edge{
int pre, to;
};
int n, m, cnt = 1, idx, tot, root;
int head[MAXN], dfn[MAXN], low[MAXN], col[MAXN], fa[MAXN];
bool iscut[MAXM << 1], vis[MAXN];
stack<int> s;
edge e[MAXM << 1];
vector<int> g[MAXN];
void add_edge(int u, int v){
e[++cnt].pre = head[u];
e[cnt].to = v;
head[u] = cnt;
}
void tarjan(int now){
low[now] = dfn[now] = ++idx; s.push(now);
int son = 0;
for(int i = head[now]; i; i = e[i].pre){
if(!dfn[e[i].to]){
tarjan(e[i].to);
low[now] = min(low[now],low[e[i].to]);
son++;
if(now == root && son > 1) iscut[now] = true;
else if(now != root && low[e[i].to] > dfn[now]) iscut[i] = iscut[i ^ 1] = true;
}
low[now] = min(low[now],dfn[e[i].to]);
}
if(dfn[now] == low[now]){
tot++;
do{
col[s.top()] = tot;
s.pop();
}while(!s.empty() && s.top() != now);
}
}
void dfs(int now){
int siz = g[now].size();
vis[now] = true;
for(int i = 0; i < siz; i++){
if(!vis[g[now][i]]){
fa[g[now][i]] = now;
dfs(g[now][i]);
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i = 1; i <= m; i++){
int u, v;
scanf("%d%d",&u,&v);
add_edge(u, v); add_edge(v, u);
}
for(int i = 1; i <= n; i++){
if(!dfn[i]){
root = i;
tarjan(i);
}
}
for(int now = 1; now <= n; now++){
for(int i = head[now]; i; i = e[i].pre){
if(col[now] != col[e[i].to]){
g[col[now]].push_back(col[e[i].to]);
g[col[e[i].to]].push_back(col[now]);
}
}
}
dfs(col[1]);
for(int i = 1; i <= n; i++) printf("%d ",col[i]);
printf("\n");
return 0;
}