#include <bits/stdc++.h>   using namespace std;   const int N = 500010;   struct edge {     int nxt, t;   } e[N * 3];   int head[N], edge_cnt;   void add_edge(int x, int y) {     e[edge_cnt] = (edge){head[x], y};     head[x] = edge_cnt++;   }   int dfn[N], low[N], Tar_cnt, stk[N], stk_top, loop_cnt, ID[N], P[N], tot, st[N],       ed[N];   void Tarjan(int x, int f) {     dfn[x] = low[x] = ++Tar_cnt;     stk[++stk_top] = x;     int i;     for (i = head[x]; ~i; i = e[i].nxt) {       int to = e[i].t;       if (to == f) {         continue;       }       if (dfn[to] == 0) {         Tarjan(to, x);         low[x] = min(low[x], low[to]);       } else {         low[x] = min(low[x], dfn[to]);       }     }     if (low[x] == dfn[x]) {       int y;       loop_cnt++;       st[x] = tot + 1;       do {         y = stk[stk_top--];         ID[y] = loop_cnt;         P[++tot] = y;       } while (x != y);       ed[x] = tot;     }   }   int D[N], Mx[N][2], dis[N], Fa[N];   bool vis[N];   void cmp(int x, int y) {     if (dis[Mx[x][0]] < dis[y]) {       Mx[x][1] = Mx[x][0];       Mx[x][0] = y;     } else if (dis[Mx[x][1]] < dis[y]) {       Mx[x][1] = y;     }   }   void BFS(int n) {     int L = 1, R = 1, i;     D[1] = 1;     vis[1] = 1;     while (L <= R) {       int x = D[L++];       for (i = head[x]; ~i; i = e[i].nxt) {         int to = e[i].t;         if (vis[to]) {           continue;         }         vis[to] = 1;         Fa[to] = x;         D[++R] = to;       }     }     dis[0] = -1;     for (i = n; i > 1; i--) {       int x = D[i], y = Fa[x];       if (ID[x] != ID[y]) {         cmp(y, x);       }       dis[y] = max(dis[y], dis[x] + 1);     }   }   struct node {     int id, w;   } Q[N << 1];   int G[N], val[N], Ans[N], dp[N];   void Push(int &L, int &R, node x) {     while (L <= R && Q[R].w <= x.w) {       R--;     }     Q[++R] = x;   }   void Pop1(int &L, int x) {     if (Q[L].id < x) {       L++;     }   }   void Pop2(int &L, int x) {     if (Q[L].id > x) {       L++;     }   }   void Solve(int S, int f, int Fr) {     int i, j, d = ed[S] - st[S] + 1, k, L, R;     dp[S] = Fr;     if (d > 1) {       for (i = st[S]; i <= ed[S]; i++) {         int x = P[i], t = dis[Mx[x][0]] + 1;         G[i - st[S] + 1] = x;         Ans[x] = t;         if (x == S) {           val[i - st[S] + 1] = max(Fr, t);         } else {           val[i - st[S] + 1] = t;         }       }       L = 1, R = 0, k = d / 2;       for (i = d - k + 1; i <= d; i++) {         Push(L, R, (node){i - d, val[i] - (i - d)});       }       for (i = 1; i <= d; i++) {         Pop1(L, i - k);         dp[G[i]] = max(dp[G[i]], Q[L].w + i);         Push(L, R, (node){i, val[i] - i});       }       L = 1, R = 0, k = (d - 1) / 2;       for (i = k; i >= 1; i--) {         Push(L, R, (node){i + d, val[i] + (i + d)});       }       for (i = d; i >= 1; i--) {         Pop2(L, i + k);         dp[G[i]] = max(dp[G[i]], Q[L].w - i);         Push(L, R, (node){i, val[i] + i});       }     } else {       Ans[S] = max(Fr, dis[Mx[S][0]] + 1);     }     for (i = st[S]; i <= ed[S]; i++) {       int x = P[i];       for (j = head[x]; ~j; j = e[j].nxt) {         int to = e[j].t;         if (ID[x] == ID[to] || to == f) {           continue;         }         if (Mx[x][0] == to) {           Solve(to, x, max(dp[x] + 1, dis[Mx[x][1]] + 2));         } else {           Solve(to, x, max(dp[x] + 1, dis[Mx[x][0]] + 2));         }       }     }   }   int main() {     int n, m, i;     scanf( %d%d , &n, &m);     memset(head + 1, -1, sizeof(int) * 1 * n);     for (i = 1; i <= m; i++) {       int x, y;       scanf( %d%d , &x, &y);       add_edge(x, y);       add_edge(y, x);     }     memset(dfn + 1, 0, sizeof(int) * 1 * n);     Tarjan(1, 0);     BFS(n);     Solve(1, 0, 0);     for (i = 1; i <= n; i++) {       printf( %d n , max(Ans[i], dp[i]));     }     return 0;   }