#include <bits/stdc++.h>
using namespace std;
template <class T>
inline void Read(T &x) {
  int f = 1;
  char t = getchar();
  while (t < '0' || t > '9') {
    if (t == '-') f = -1;
    t = getchar();
  }
  x = 0;
  while (t >= '0' && t <= '9') {
    x = x * 10 + t - '0';
    t = getchar();
  }
  x *= f;
}
const int maxn = 2005;
const int maxm = 200005;
int n, m;
struct graph {
  int fst[maxn], u[maxm], v[maxm], nxt[maxm], e_cn;
  int dfn[maxn], low[maxn], belong[maxn], deg[maxn], flag[maxn], siz[maxn], sz,
      dfn_clock;
  int q[maxn], cur, r;
  bool vis[maxn];
  int endpoint, max_p, maxdis, cn_sz;
  graph() {
    memset(fst, -1, sizeof(fst));
    memset(flag, 0, sizeof(flag));
    memset(belong, 0, sizeof(belong));
    sz = dfn_clock = cur = 0, e_cn = -1;
  }
  inline void addedge(int x, int y) {
    e_cn++;
    u[e_cn] = x, v[e_cn] = y;
    nxt[e_cn] = fst[x], fst[x] = e_cn;
  }
  void tarjan(int cn, int fa) {
    dfn[cn] = low[cn] = ++dfn_clock;
    q[++r] = cn, flag[cn] = 2;
    for (register int i = fst[cn]; i != -1; i = nxt[i]) {
      if (v[i] != fa) {
        if (!flag[v[i]]) {
          tarjan(v[i], cn);
          low[cn] = min(low[cn], low[v[i]]);
        } else if (flag[v[i]] == 2) {
          low[cn] = min(low[cn], dfn[v[i]]);
        }
      }
    }
    if (dfn[cn] == low[cn]) {
      cur = 0, sz++;
      do {
        cur = q[r], r--;
        belong[cur] = sz;
        flag[cur] = 1;
      } while (cur != cn);
    }
  }
  void restruct(graph &to) {
    to.sz = sz;
    for (register int i = 0; i <= e_cn; i++) {
      int x = u[i], y = v[i];
      if (belong[x] != belong[y]) {
        to.addedge(belong[y], belong[x]);
        to.deg[belong[x]]++;
      }
    }
    for (register int i = 1; i <= n; i++) to.siz[belong[i]]++;
  }
  void dfs(int cn, int dis) {
    vis[cn] = true;
    q[++r] = cn;
    if (deg[cn] > 1) cn_sz++;
    if (max_p == -1 || dis > maxdis) maxdis = dis, max_p = cn;
    for (register int i = fst[cn]; i != -1; i = nxt[i]) {
      if (!vis[v[i]]) {
        dfs(v[i], dis + 1);
      }
    }
  }
  long long calc() {
    long long re = 0;
    int area_sz = 0;
    for (register int i = 1; i <= sz; i++) {
      re += siz[i] - 1;
    }
    for (register int i = 1; i <= sz; i++) {
      if (!vis[i]) {
        max_p = -1, maxdis = r = 0;
        dfs(i, 1);
        while (r) vis[q[r--]] = false;
        endpoint = max_p, max_p = -1, maxdis = 0, cn_sz = 0;
        dfs(endpoint, 1);
        area_sz++;
        if (cn_sz > 2) re += cn_sz - (maxdis - 2);
      }
    }
    re += area_sz - 1;
    return re;
  }
};
graph initgraph, newgraph;
void input() {
  int x, y;
  Read(n), Read(m);
  for (register int i = 1; i <= m; i++) {
    Read(x), Read(y);
    initgraph.addedge(x, y);
    initgraph.addedge(y, x);
  }
}
void solve() {
  long long ans = 0;
  for (register int i = 1; i <= n; i++) {
    if (!initgraph.flag[i]) {
      initgraph.r = 0;
      initgraph.tarjan(i, -1);
    }
  }
  initgraph.restruct(newgraph);
  ans = newgraph.calc();
  cout << ans << endl;
}
int main() {
  input();
  solve();
  return 0;
}
