#include <bits/stdc++.h>
using namespace std;
inline int readInt() {
  char c;
  int tmp = 0, x = 1;
  c = getchar();
  while (c > '9' || c < '0') {
    if (c == '-') x = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    tmp = tmp * 10 + c - '0';
    c = getchar();
  }
  return tmp * x;
}
const int maxN = 2000 + 10;
const int maxM = 100000 + 10;
int Head[maxN], eg[maxM << 1], nxt[maxM << 1], tot = 1;
void addEdge(int u, int v) {
  eg[++tot] = v;
  nxt[tot] = Head[u];
  Head[u] = tot;
  eg[++tot] = u;
  nxt[tot] = Head[v];
  Head[v] = tot;
}
bool isbri[maxM << 2];
int dfn[maxN], low[maxN], dfsclock = 0;
void tarjan(int v, int InEdge) {
  dfn[v] = low[v] = ++dfsclock;
  for (int i = Head[v]; i; i = nxt[i]) {
    int u = eg[i];
    if (!dfn[u]) {
      tarjan(u, i);
      low[v] = min(low[v], low[u]);
      if (low[u] > dfn[v]) isbri[i] = isbri[i ^ 1] = true;
    } else if (i != (InEdge ^ 1))
      low[v] = min(low[v], dfn[u]);
  }
}
int bccno[maxN], num = 0, bccsiz[maxN];
void dfs(int v) {
  bccno[v] = num;
  bccsiz[num]++;
  for (int i = Head[v]; i; i = nxt[i]) {
    int u = eg[i];
    if (!bccno[u] && !isbri[i]) dfs(u);
  }
}
vector<int> g[maxN];
void new_addEdge(int u, int v) {
  g[u].push_back(v);
  g[v].push_back(u);
}
bool vis[maxN], isLeaf[maxN];
int tmp = 0, tmpmax = -1, tmpleaf = 0, Leaf[maxN], siz[maxN], rot[maxN],
    cnt = 0, Fa[maxN], Belong[maxN];
void predfs(int v, int fa) {
  siz[v] = 1;
  Fa[v] = fa;
  Belong[v] = cnt;
  if ((int)g[v].size() == 0 || (int)g[v].size() == 1)
    Leaf[cnt]++, isLeaf[v] = true;
  for (int i = 0; i < (int)g[v].size(); i++) {
    int u = g[v][i];
    if (u != fa) predfs(u, v), siz[v] += siz[u];
  }
}
void FindLongest(int v, int fa, int D, int lev) {
  if (tmp < D) tmp = D, tmpmax = v, tmpleaf = lev;
  for (int i = 0; i < (int)g[v].size(); i++) {
    int u = g[v][i];
    if (u != fa) FindLongest(u, v, D + (!isLeaf[u]), lev + isLeaf[u]);
  }
}
int FindDiameter(int v) {
  tmp = 0, tmpmax = -1;
  for (int i = 0; i < (int)g[v].size(); i++) {
    int u = g[v][i];
    FindLongest(u, v, 1, 0);
  }
  if (!(~tmpmax)) return 0;
  int vv = tmpmax;
  tmp = 0, tmpmax = -1, tmpleaf = 0;
  FindLongest(vv, -1, 1, isLeaf[vv]);
  return tmp - tmpleaf;
}
int n, m;
int main() {
  n = readInt(), m = readInt();
  int u, v;
  for (int i = 1; i <= m; i++) {
    u = readInt(), v = readInt();
    addEdge(u, v);
  }
  for (int i = 1; i <= n; i++) {
    if (!dfn[i]) tarjan(i, 0);
  }
  for (int i = 1; i <= n; i++) {
    if (!bccno[i]) {
      num++;
      dfs(i);
    }
  }
  for (int i = 2; i <= tot; i += 2) {
    if (bccno[eg[i]] != bccno[eg[i ^ 1]]) {
      new_addEdge(bccno[eg[i]], bccno[eg[i ^ 1]]);
    }
  }
  int ans = 0;
  for (int i = 1; i <= num; i++) ans += bccsiz[i] - 1;
  cnt = 0;
  for (int i = 1; i <= num; i++) {
    if (!Belong[i]) cnt++, rot[cnt] = i, predfs(i, -1);
  }
  ans += cnt - 1;
  for (int i = 1; i <= cnt; i++) {
    int d = FindDiameter(rot[i]);
    ans += siz[rot[i]] - d - Leaf[i];
  }
  printf("%d\n", ans);
  return 0;
}
