#include <bits/stdc++.h>   using namespace std;   const int maxn = 500000;   template <typename T>   class graph {    public:     struct edge {       int from;       int to;       T cost;     };     vector<edge> edges;     vector<vector<int>> g;     int n;     graph(int _n) : n(_n) { g.resize(n); }     virtual int add(int from, int to, T cost) = 0;   };   template <typename T>   class undigraph : public graph<T> {    public:     using graph<T>::edges;     using graph<T>::g;     using graph<T>::n;     undigraph(int _n) : graph<T>(_n) {}     int add(int from, int to, T cost = 1) {       assert(0 <= from && from < n && 0 <= to && to < n);       int id = (int)edges.size();       g[from].push_back(id);       g[to].push_back(id);       edges.push_back({from, to, cost});       return id;     }   };   template <typename T>   class cycle_finder {    public:     vector<int> was;     vector<int> st;     vector<vector<int>> cycles;     const graph<T> &g;     int bound_cnt;     int bound_size;     int total_size = 0;     cycle_finder(graph<T> &_g, int _bound_cnt = 1 << 30,                  int _bound_size = 1 << 30)         : g(_g), bound_cnt(_bound_cnt), bound_size(_bound_size) {       was.assign(g.n, -1);     }     void dfs(int v, int pe) {       if ((int)cycles.size() >= bound_cnt || total_size >= bound_size) {         return;       }       was[v] = (int)st.size();       for (int id : g.g[v]) {         if (id == pe) {           continue;         }         auto &e = g.edges[id];         int to = e.from ^ e.to ^ v;         if (was[to] >= 0) {           vector<int> cycle(1, id);           for (int j = was[to]; j < (int)st.size(); j++) {             cycle.push_back(st[j]);           }           cycles.push_back(cycle);           total_size += (int)cycle.size();           if ((int)cycles.size() >= bound_cnt || total_size >= bound_size) {             return;           }           continue;         }         if (was[to] == -1) {           st.push_back(id);           dfs(to, id);           st.pop_back();         }       }       was[v] = -2;     };     void find_cycles() {       for (int i = 0; i < g.n; i++) {         if (was[i] == -1) {           dfs(i, -1);         }       }     }   };   int main() {     ios::sync_with_stdio(false);     cin.tie(0);     if (fopen( input.in ,  r )) {       freopen( input.in ,  r , stdin);       freopen( output.out ,  w , stdout);     }     int n, m;     cin >> n >> m;     undigraph<int> g(n);     int dp[maxn];     int subtractI[maxn];     for (int i = 0; i < n; i++) dp[i] = 1;     for (int i = 0; i < m; i++) {       int a, b;       cin >> a >> b;       a--, b--;       g.add(a, b, i + 1);       subtractI[i] = -1;     }     cycle_finder<int> cycles(g);     cycles.find_cycles();     for (auto &cycle : cycles.cycles) {       int pos = (int)(min_element(cycle.begin(), cycle.end()) - cycle.begin());       rotate(cycle.begin(), cycle.begin() + pos, cycle.end());       pos = (int)(max_element(cycle.begin(), cycle.end()) - cycle.begin());       bool subCycle = true;       for (int i = 0; i < pos - 1; i++) {         int costA = g.edges[cycle[i]].cost;         int costB = g.edges[cycle[i + 1]].cost;         if (costA > costB) {           subCycle = false;           break;         }       }       for (int i = pos; i < cycle.size() - 1; i++) {         int costA = g.edges[cycle[i]].cost;         int costB = g.edges[cycle[i + 1]].cost;         if (costA < costB) {           subCycle = false;           break;         }       }       if (subCycle) {         subtractI[cycle[0]] = cycle[pos];       }     }     int hist[maxn];     for (int i = m - 1; i >= 0; i--) {       int a = g.edges[i].from, b = g.edges[i].to;       int sum = dp[a] + dp[b];       if (subtractI[i] != -1) sum -= hist[subtractI[i]];       dp[a] = sum;       dp[b] = sum;       hist[i] = sum;     }     for (int i = 0; i < n; i++) cout << dp[i] - 1 <<    ;   }