#include <bits/stdc++.h>
using namespace std;
int n, m;
int dfn[20010], low[20010], col[20010], dp[20010];
bool vis[20010];
bool brg[1000010];
vector<pair<int, int> > G[20010];
map<pair<int, int>, bool> mp;
vector<int> nG[20010];
int cnt, prt;
int ans;
int res;
pair<int, int> edge[1000010];
void tarjan(int x, int p) {
  dfn[x] = low[x] = ++cnt;
  for (int i = 0; i < G[x].size(); i++) {
    int y = G[x][i].first, id = G[x][i].second;
    if (!dfn[y]) {
      tarjan(y, x);
      low[x] = min(low[x], low[y]);
      if (low[y] > dfn[x]) brg[id] = true;
    } else if (dfn[y] < dfn[x] && y != p) {
      low[x] = min(low[x], low[y]);
    }
  }
}
void dfs(int x) {
  col[x] = prt;
  for (int i = 0; i < G[x].size(); i++) {
    int y = G[x][i].first, id = G[x][i].second;
    if (col[y] || brg[id]) continue;
    dfs(y);
  }
}
void solve(int x) {
  vis[x] = true;
  int mx1 = 0, mx2 = 0;
  for (int i = 0; i < nG[x].size(); i++) {
    int y = nG[x][i];
    if (vis[y]) continue;
    solve(y);
    if (dp[y] > mx1) {
      mx2 = mx1;
      mx1 = dp[y];
    } else if (dp[y] > mx2) {
      mx2 = dp[y];
    }
  }
  if (nG[x].size() == 1) {
    ans--;
    return;
  }
  dp[x] = mx1 + 1;
  res = max(res, mx1 + mx2 + 1);
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    G[x].push_back(make_pair(y, i));
    G[y].push_back(make_pair(x, i));
    edge[i] = make_pair(x, y);
  }
  for (int i = 1; i <= n; i++) {
    if (dfn[i]) continue;
    tarjan(i, 0);
  }
  for (int i = 1; i <= n; i++) {
    if (col[i]) continue;
    ++prt;
    dfs(i);
  }
  for (int i = 1; i <= m; i++) {
    if (!brg[i]) continue;
    int x = col[edge[i].first], y = col[edge[i].second];
    if (mp[make_pair(x, y)]) continue;
    mp[make_pair(x, y)] = mp[make_pair(y, x)] = true;
    nG[x].push_back(y);
    nG[y].push_back(x);
  }
  ans = n - 1;
  for (int i = 1; i <= prt; i++) {
    if (vis[i]) continue;
    ans++;
    res = 0;
    solve(i);
    ans -= res;
  }
  printf("%d", ans);
  return 0;
}
