#include <bits/stdc++.h>
using namespace std;
struct UnionFind {
  int parent[2010], rank[2010];
  UnionFind(int n) {
    int i;
    for ((i) = 0; (i) < (int)(n); (i)++) {
      parent[i] = i;
      rank[i] = 1;
    }
  }
  int root(int x) {
    if (parent[x] != x) parent[x] = root(parent[x]);
    return parent[x];
  }
  void connect(int x, int y) {
    int rx = root(x), ry = root(y);
    if (rx == ry) return;
    if (rank[rx] > rank[ry]) {
      parent[ry] = rx;
      rank[rx] += rank[ry];
    }
    if (rank[rx] <= rank[ry]) {
      parent[rx] = ry;
      rank[ry] += rank[rx];
    }
  }
};
int N;
bool graph[2010][2010];
int C, id[2010], lowlink[2010];
int V;
map<int, int> mp;
bool tree[2010][2010];
bool used[2010];
int dfs_lowlink(int p, int v) {
  int ans = C, i;
  id[v] = C;
  C++;
  for ((i) = 0; (i) < (int)(N); (i)++)
    if (i != p && graph[v][i]) {
      if (id[i] != -1)
        ans = min(ans, id[i]);
      else
        ans = min(ans, dfs_lowlink(v, i));
    }
  return lowlink[v] = ans;
}
void calc_lowlink(void) {
  int i;
  C = 0;
  for ((i) = 0; (i) < (int)(N); (i)++) id[i] = -1;
  for ((i) = 0; (i) < (int)(N); (i)++)
    if (id[i] == -1) dfs_lowlink(-1, i);
}
void dfs(int p, int v, int &u, int &d) {
  int i;
  used[v] = true;
  u = v;
  d = 0;
  for ((i) = 0; (i) < (int)(V); (i)++)
    if (i != p && tree[v][i]) {
      int u2, d2;
      dfs(v, i, u2, d2);
      if (d2 + 1 > d) {
        d = d2 + 1;
        u = u2;
      }
    }
}
int main(void) {
  int M, a, b, i, j;
  scanf("%d%d", &N, &M);
  for ((i) = 0; (i) < (int)(M); (i)++) {
    scanf("%d%d", &a, &b);
    a--;
    b--;
    graph[a][b] = graph[b][a] = true;
  }
  calc_lowlink();
  UnionFind uf(N);
  for ((i) = 0; (i) < (int)(N); (i)++)
    for ((j) = 0; (j) < (int)(N); (j)++)
      if (graph[i][j] && id[i] < id[j] && lowlink[j] < id[j]) uf.connect(i, j);
  for ((i) = 0; (i) < (int)(N); (i)++) mp[uf.root(i)] = 0;
  for (__typeof((mp).begin()) itr = (mp).begin(); itr != (mp).end(); itr++) {
    (itr->second) = V;
    V++;
  }
  for ((i) = 0; (i) < (int)(N); (i)++)
    for ((j) = 0; (j) < (int)(N); (j)++)
      if (graph[i][j] && id[i] < id[j] && lowlink[j] == id[j])
        tree[mp[uf.root(i)]][mp[uf.root(j)]] =
            tree[mp[uf.root(j)]][mp[uf.root(i)]] = true;
  int ans = N - 1;
  for ((i) = 0; (i) < (int)(V); (i)++) {
    int deg = 0;
    for ((j) = 0; (j) < (int)(V); (j)++)
      if (tree[i][j]) deg++;
    if (deg == 1)
      ans--;
    else if (deg == 0)
      ans -= 2;
  }
  for ((i) = 0; (i) < (int)(V); (i)++)
    if (!used[i]) {
      int u, v, d;
      dfs(-1, i, u, d);
      dfs(-1, u, v, d);
      ans -= d - 2;
    }
  cout << ans << endl;
  return 0;
}
