#include <bits/stdc++.h>
using namespace std;
const int maxn = 10100, maxm = 610000;
int pre[maxm], now[maxm], son[maxm];
int n, m;
namespace Dinit {
int Getchar() {
  int tmp = 0;
  char ch;
  while (ch = getchar())
    if (ch >= '0' && ch <= '9') break;
  for (; ch >= '0' && ch <= '9'; ch = getchar()) tmp = tmp * 10 + ch - '0';
  return tmp;
}
int tot;
void cc(int a, int b) {
  pre[++tot] = now[a];
  now[a] = tot;
  son[tot] = b;
}
void make(int a, int b) {
  cc(a, b);
  cc(b, a);
}
void init() {
  n = Getchar(), m = Getchar();
  for (int i = 1; i <= m; i++) {
    int a = Getchar(), b = Getchar();
    make(a, b);
  }
}
}  // namespace Dinit
bool ok[maxn];
namespace Dfind {
int asd = 0, sign;
int number[maxn];
int dfn[maxn], num, sum, low[maxn], stack[maxn];
bool instack[maxn];
int ans;
void dfs(int x, int fa) {
  asd++;
  dfn[x] = low[x] = ++sign;
  instack[x] = true;
  ok[x] = true;
  stack[++sum] = x;
  for (int p = now[x]; p; p = pre[p])
    if (son[p] != fa)
      if (!dfn[son[p]]) {
        dfs(son[p], x);
        low[x] = min(low[son[p]], low[x]);
      } else if (instack[son[p]])
        low[x] = min(dfn[son[p]], low[x]);
  if (dfn[x] == low[x]) {
    num++;
    int asdaa = 0;
    while (stack[sum + 1] != x) {
      instack[stack[sum]] = false;
      number[stack[sum]] = num;
      sum--;
      asdaa++;
    }
    ans += asdaa - 1;
  }
}
int tot;
int dist[maxn][2];
int pre1[maxm], ru[maxn], now1[maxm], son1[maxm];
void cc(int a, int b) {
  ru[b]++;
  pre1[++tot] = now1[a];
  now1[a] = tot;
  son1[tot] = b;
}
void make(int a, int b) {
  cc(a, b);
  cc(b, a);
}
void make_edge() {
  for (int i = 1; i <= n; i++)
    if (number[i])
      for (int p = now[i]; p; p = pre[p])
        if (number[i] != number[son[p]])
          if (number[i] <= number[son[p]]) make(number[i], number[son[p]]);
}
void dfs1(int x, int fa) {
  for (int p = now1[x]; p; p = pre1[p])
    if (son1[p] != fa) {
      dfs1(son1[p], x);
      if (dist[son1[p]][0] + 1 > dist[x][0]) {
        dist[x][0] = dist[son1[p]][0] + 1;
        dist[x][1] = dist[son1[p]][1];
      }
    }
  if (!dist[x][0]) dist[x][1] = x;
}
int find(int x) {
  memset(now1, 0, sizeof(now1));
  memset(dist, 0, sizeof(dist));
  memset(number, 0, sizeof(number));
  memset(ru, 0, sizeof(ru));
  tot = 0, num = 0, asd = 0, sign = 0;
  ans = 0;
  int point1 = 0;
  dfs(x, x);
  make_edge();
  dfs1(number[x], number[x]);
  point1 = dist[number[x]][1];
  memset(dist, 0, sizeof(dist));
  dfs1(point1, point1);
  if (num == 1) return ans;
  ans += num - dist[point1][0] + 1;
  for (int i = 1; i <= num; i++)
    if (ru[i] <= 1) ans--;
  return ans;
}
}  // namespace Dfind
namespace Dwork {
void work() {
  int ans = 0;
  int tot = 0;
  for (int i = 1; i <= n; i++)
    if (!ok[i]) {
      ans += Dfind::find(i);
      tot++;
    }
  printf("%d\n", ans + tot - 1);
}
}  // namespace Dwork
int main() {
  Dinit::init();
  Dwork::work();
  return 0;
}
