#ifndef LOCAL
#include <bits/stdc++.h>
#define csf std::cerr.setstate(std::ios_base::failbit)
#define db(x)
#else
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <vector>
#define db(x) cerr << __FUNCTION__ << " L" << __LINE__ << " " << #x " = " << (x) << endl
#define csf
#endif
#define ll long long
#define f(x, y, z) for (ll x = (y); x <= (z); x++)
using namespace std;
inline ll read();
const ll INF = 0x3f3f3f3f3f3f3f3f, N = 1e5 + 10;
ll n, m;
vector<ll> h[N];
ll id, dfn[N], gbk[N];
bool isk[N];
ll stk[N], stp;
ll fr[N];
ll ans = 1;
void tarjan(ll x, ll fa = 0)
{
ll double_edge = 1;
dfn[x] = gbk[x] = ++id;
isk[x] = 1;
stk[++stp] = x;
for (auto v : h[x])
{
if (v == fa && double_edge)
{
double_edge--;
continue;
}
if (dfn[v] || v == fa)
{
if (isk[v])
gbk[x] = min(gbk[x], dfn[v]);
}
else
{
tarjan(v, x);
if (gbk[v] > dfn[x])
{
while (stk[stp] != v)
{
fr[stk[stp]] = v;
isk[stk[stp]] = 0;
stp--;
}
fr[stk[stp]] = v;
isk[stk[stp]] = 0;
stp--;
}
else
gbk[x] = min(gbk[x], gbk[v]);
}
}
}
struct edge
{
ll x, y;
} a[N];
bool kkk[N];
void dfs(ll x = 1, ll fa = 0)
{
bool leaf = 1;
for (auto v : h[x])
{
if (v == fa)
continue;
dfs(v, x);
leaf = 0;
}
ans += leaf;
}
signed main()
{
csf;
cin >> n >> m;
f(i, 1, m)
{
ll x, y;
cin >> x >> y;
h[x].push_back(y);
h[y].push_back(x);
a[i] = {x, y};
}
f(i, 1, n) if (dfn[i] == 0)
tarjan(i);
f(i, 1, n)
{
if (fr[i] == 0)
{
fr[i] = 1;
}
h[i].clear();
}
f(i, 1, m)
{
if (fr[a[i].x] == fr[a[i].y])
continue;
h[fr[a[i].x]].push_back(fr[a[i].y]);
h[fr[a[i].y]].push_back(fr[a[i].x]);
}
dfs();
db(ans);
cout << ceil(ans / 2.0);
return 0;
}