#include <bits/stdc++.h>
using namespace std;
int n, m, ans, du[2010], d[2010], mx, sz, dp[2010];
int num, k, now, a[2010], dfn[2010], low[2010], st[2010], b[2010];
bool in[2010];
int cnt, head[2010], to[200010], nxt[200010];
vector<int> v[2010];
void add(int x, int y) {
  cnt++;
  to[cnt] = y;
  nxt[cnt] = head[x];
  head[x] = cnt;
}
void tarjan(int x, int fa) {
  now++;
  dfn[x] = low[x] = now;
  st[k] = x;
  k++;
  in[x] = true;
  for (int i = head[x]; i; i = nxt[i]) {
    int y = to[i];
    if (y == fa) {
      continue;
    }
    if (!dfn[y]) {
      tarjan(y, x);
      low[x] = min(low[x], low[y]);
    } else if (in[y]) {
      low[x] = min(low[x], dfn[y]);
    }
  }
  if (low[x] == dfn[x]) {
    num++;
    int y;
    do {
      y = st[k - 1];
      a[y] = num;
      in[y] = false;
      k--;
    } while (k > 0 && y != x);
  }
}
void dfs(int x) {
  dfn[x] = true;
  for (int i = 0; i < v[x].size(); i++) {
    int y = v[x][i];
    if (dfn[y]) {
      continue;
    }
    dfs(y);
    if (du[y] > 1) {
      mx = max(mx, dp[x] + dp[y] + 1);
      dp[x] = max(dp[x], dp[y]);
    }
  }
  if (du[x] <= 1) {
    return;
  }
  sz++;
  dp[x]++;
  mx = max(mx, dp[x]);
}
void work(int x) {
  if (du[x] > 1) {
    dfs(x);
    return;
  }
  for (int i = 0; i < v[x].size(); i++) {
    int y = v[x][i];
    if (du[y] > 1) {
      dfs(y);
      return;
    }
  }
  dfs(x);
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < m; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    add(x, y);
    add(y, x);
  }
  for (int i = 1; i <= n; i++) {
    if (!dfn[i]) {
      tarjan(i, 0);
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = head[i]; j; j = nxt[j]) {
      int y = to[j];
      if (a[i] != a[y]) {
        v[a[i]].push_back(a[y]);
        du[a[i]]++;
      }
    }
  }
  ans = n - num;
  memset(dfn, 0, sizeof(dfn));
  for (int i = 1; i <= num; i++) {
    if (!dfn[i]) {
      ans++;
      mx = sz = 0;
      work(i);
      ans += sz - mx;
    }
  }
  ans--;
  printf("%d\n", ans);
  return 0;
}
