#include<deque>
#include<queue>
#include<vector>
#include<algorithm>
#include<iostream>
#include<set>
#include<cmath>
#include<tuple>
#include<string>
#include<chrono>
#include<functional>
#include<iterator>
#include<random>
#include<unordered_set>
#include<unordered_map>
#include<array>
#include<map>
#include<bitset>
#include<iomanip>
using namespace std;
typedef long long int llint;
typedef long double lldo;
#define mp make_pair
#define mt make_tuple
#define pub push_back
#define puf push_front
#define pob pop_back
#define pof pop_front
#define fir first
#define sec second
#define res resize
#define ins insert
#define era erase
#define dme cout<<"IMPOSSIBLE"<<endl;return 0
//ios::sync_with_stdio(false);
//std::cin.tie(0);
//<< setprecision(20)
//12:15~
const int mod=1e9+7;
const int big=1e9+100;
const long double pai=3.141592653589793238462643383279502884197;
const long double ena=2.71828182845904523536;
const long double eps=1e-7;
template <class T,class U>void mineq(T& a,U b){if(a>b){a=b;}}
template <class T,class U>void maxeq(T& a,U b){if(a<b){a=b;}}
llint gcd(llint a,llint b){if(a%b==0){return b;}else return gcd(b,a%b);}
llint lcm(llint a,llint b){return a/gcd(a,b)*b;}
class nizyu{public:
	//2????????£?????????????§£???????????????!!!!!!!
	//SCC???????????????????????????
	vector<vector<int>>road;//?????¨??????
	vector<int>imo;
	vector<int>name;
	vector<bool>used;//?¨?????????? ????????§????????\????????¨?????§??????
	vector<bool>uuuu;
	int n,niznum;//niznum=??£???????????¨????????????
	nizyu(void){}
	nizyu(int in){n=in;road.res(n);}
	void add_road(int a,int b){road[a].pub(b);road[b].pub(a);}
	void sai_dfs(int ter,int oya){
		name[ter]=niznum;
		//cerr<<"name["<<ter<<"]="<<niznum<<endl;
		for(auto it:road[ter]){
			if(it==oya){continue;}
			if(name[it]!=-1){continue;}
			sai_dfs(it,ter);
		}
	}
	int dfs_tree(int ter,int oya=-1){
		//cerr<<"ter="<<ter<<"oya="<<oya<<endl;
		//dfs??¨?????????
		if(used[ter]){return 0;}
		used[ter]=true;
		int koutai=0;
		bool che=true;
		for(auto it:road[ter]){
			if(it==oya&&che){che=false;continue;}//?????????????????????(??\??????????????§)
			if(used[it]&&(!uuuu[it])){koutai++;imo[it]++;}
			else{koutai+=dfs_tree(it,ter);}
		}
		koutai-=imo[ter];
		//cerr<<"ter="<<ter<<"koutai="<<koutai<<endl;
		uuuu[ter]=true;
		if(koutai==0){sai_dfs(ter,oya);niznum++;}//???
		return koutai;
	}
	void do_nizyu(void){
		//???????????£?????????????§£??????
		niznum=0;
		imo.res(n);
		used.res(n);
		uuuu.res(n);
		name.res(n);for(auto &it:name){it=-1;}
		for(int i=0;i<n;i++){dfs_tree(i);}
		//for(auto it:name){cerr<<"name="<<it<<endl;}
	}
	vector<vector<int>>Croad;//??°????????????
	void chain_niz(void){
		Croad.res(niznum);
		for(int i=0;i<n;i++){
			for(auto it:road[i]){Croad[name[i]].pub(name[it]);}
		}
		for(int i=0;i<niznum;i++){
			sort(Croad[i].begin(),Croad[i].end());
			Croad[i].erase(unique(Croad[i].begin(),Croad[i].end()),Croad[i].end());
			auto itr=find(Croad[i].begin(),Croad[i].end(),i);
			if(itr!=Croad[i].end()){Croad[i].erase(itr);}
		}
	}
};
nizyu aa;
vector<int> kazu;
vector<bool>sod;
pair<int,int> solve(int ter=0,int oya=-1){
	sod[ter]=true;
	int hai=kazu[ter],no=0;
	for(auto it:aa.Croad[ter]){
		if(it==oya){continue;}
		auto p=solve(it,ter);
		hai+=p.sec;no+=p.fir;
	}
	maxeq(hai,no);
	return mp(hai,no);
}
//pair,??????,?????????
int main(void){
	int i,n,m;cin>>n>>m;
	aa.n=n;aa.road.res(n);
	for(i=0;i<m;i++){
		int a,b;cin>>a>>b;
		aa.add_road(a,b);
	}
	aa.do_nizyu();
	aa.chain_niz();
	kazu.res(aa.niznum);
	sod.res(aa.niznum);
	for(i=0;i<n;i++){kazu[aa.name[i]]++;}
	int ans=0;
	for(i=0;i<aa.niznum;i++){if(!sod[i]){ans+=solve(i).fir;}}
	cout<<ans<<endl;
}

Measured memory_bytes: 14948