#include <bits/stdc++.h>
using namespace std;
int n, m, a, b, i, len, j, dp[2600][3][2600], Dp[3][2600], Dp1[3][2600],
    zhan[2600][2600], zhan1[2600], fa[2600], h[2600], siz[2600], sum[2600];
bool used[2600];
vector<int> ve[2600], to[2600];
void dfs1(int k, int f) {
  used[k] = true;
  fa[k] = f;
  h[k] = h[f] + 1;
  for (int i = 0; i < ve[k].size(); i++)
    if (!used[ve[k][i]]) dfs1(ve[k][i], k);
}
void Find(int x, int y) {
  len++;
  if (h[x] < h[y]) swap(x, y);
  int len1 = 0, len2 = 0;
  while (h[x] > h[y]) {
    zhan[len][len1++] = x;
    siz[len]++;
    x = fa[x];
  }
  while (x != y) {
    siz[len] += 2;
    zhan[len][len1++] = x;
    zhan1[++len2] = x;
    x = fa[x];
    y = fa[y];
  }
  zhan[len][len1++] = y;
  siz[len]++;
  for (int i = len2; i; i--) zhan[len][len1++] = zhan1[i];
  for (int i = 0; i < siz[len]; i++) to[zhan[len][i]].push_back(len);
}
void Set(int dp[3][2600]) {
  for (int i = 0; i < 3; i++)
    for (int j = 0; j <= n; j++) dp[i][j] = -1000000000;
}
void dfs(int k, int up, int s) {
  int M = siz[k];
  for (int i = 0; i < M; i++)
    if (zhan[k][i] == up) {
      up = i;
      break;
    }
  for (int i = 0; i < M; i++) used[zhan[k][i]] = true;
  for (int i = 0; i < M; i++) {
    int x = zhan[k][(up + i) % M];
    if (i || s) {
      for (int j = 0; j < to[x].size(); j++)
        if (to[x][j] != k) dfs(to[x][j], x, 0);
      for (int j = 0; j < ve[x].size(); j++)
        if (!used[ve[x][j]]) {
          dfs(to[ve[x][j]][0], ve[x][j], 1);
          used[ve[x][j]] = false;
        }
    }
  }
  for (int u = 0; u < 3; u++) {
    Set(Dp);
    Dp[u][u == 1] = (u == 0);
    sum[k] = 0;
    for (int i = 0; i < M; i++) {
      sum[k]++;
      if (i) {
        Set(Dp1);
        for (int a = 0; a < 3; a++)
          for (int b = 0; b < 3; b++)
            for (int q = 0; q < sum[k]; q++)
              if ((a ^ b) != 1)
                Dp1[b][q + (b == 1)] =
                    max(Dp1[b][q + (b == 1)], Dp[a][q] + (b == 0));
        memcpy(Dp, Dp1, sizeof Dp);
      }
      int x = zhan[k][(up + i) % M];
      if (i || s) {
        for (int j = 0; j < to[x].size(); j++)
          if (to[x][j] != k) {
            int q = to[x][j];
            Set(Dp1);
            for (int a = 0; a < 3; a++)
              for (int b = 0; b <= sum[k]; b++)
                for (int c = 0; c <= sum[q]; c++)
                  if (b + c - (a == 1) >= 0)
                    Dp1[a][b + c - (a == 1)] =
                        max(Dp1[a][b + c - (a == 1)],
                            Dp[a][b] + dp[q][a][c] - (a == 0));
            sum[k] += sum[q] - 1;
            memcpy(Dp, Dp1, sizeof Dp);
          }
        for (int j = 0; j < ve[x].size(); j++)
          if (!used[ve[x][j]]) {
            int q = to[ve[x][j]][0];
            Set(Dp1);
            for (int a = 0; a < 3; a++)
              for (int b = 0; b < 3; b++)
                for (int c = 0; c <= sum[k]; c++)
                  for (int d = 0; d <= sum[q]; d++)
                    if ((a ^ b) != 1)
                      Dp1[a][c + d] =
                          max(Dp1[a][c + d], Dp[a][c] + dp[q][b][d]);
            sum[k] += sum[q];
            memcpy(Dp, Dp1, sizeof Dp);
          }
      }
    }
    for (int i = 0; i <= sum[k]; i++) {
      dp[k][u][i] = -1000000000;
      for (int j = 0; j < 3; j++)
        if ((j ^ u) != 1) dp[k][u][i] = max(dp[k][u][i], Dp[j][i]);
    }
  }
}
int main() {
  scanf("%d%d", &n, &m);
  for (i = 1; i <= m; i++) {
    scanf("%d%d", &a, &b);
    ve[a].push_back(b);
    ve[b].push_back(a);
  }
  dfs1(1, 0);
  memset(used, false, sizeof(used));
  for (i = 1; i <= n; i++)
    for (j = 0; j < ve[i].size(); j++)
      if (i < ve[i][j] && fa[ve[i][j]] != i && fa[i] != ve[i][j])
        Find(i, ve[i][j]);
  for (i = 1; i <= n; i++)
    if (!to[i].size()) Find(i, i);
  dfs(1, zhan[1][1], 1);
  for (i = 0; i <= n; i++)
    printf("%d ", max(dp[1][0][i], max(dp[1][1][i], dp[1][2][i])));
}
