#include<bits/stdc++.h> #define MAX_N 10000 usingnamespace std; template <classT> inlinevoidread(T &x){ x = 0; int c = getchar(), f = 1; for (; !isdigit(c); c = getchar()) if (c == 45) f = -1; for (; isdigit(c); c = getchar()) (x *= 10) += f*(c-'0'); } int n, m, d[MAX_N+5], c[MAX_N+5], seq[MAX_N+5]; vector <int> G[MAX_N+5]; list <int> buk[MAX_N+5]; bool mrk[MAX_N+5]; voidaddedge(int u, int v){G[u].push_back(v), G[v].push_back(u);} voidMCS(){ memset(mrk, false, sizeof mrk); for (int i = 1; i <= n; i++) buk[0].push_back(i); for (int i = 0, mx = 0, u; i < n; seq[++i] = u, mrk[u] = true) { while (!buk[mx+1].empty()) mx++; for (u = -1; u == -1; mx--) { while (!buk[mx].empty() && mrk[buk[mx].front()]) buk[mx].pop_front(); if (!buk[mx].empty()) u = buk[mx].front(); } for (int j = 0, v; j < (int)G[u].size(); j++) if (!mrk[G[u][j]]) d[v = G[u][j]]++, buk[d[v]].push_back(v); } } intColor(){ int ret = 0; memset(mrk, false, sizeof mrk); for (int i = 1, u = seq[1]; i <= n; u = seq[++i]) { for (int j = 0; j < (int)G[u].size(); j++) mrk[c[G[u][j]]] = true; for (int j = 1; !c[u]; j++) if (!mrk[j]) c[u] = j; for (int j = 0; j < (int)G[u].size(); j++) mrk[c[G[u][j]]] = false; ret = max(ret, c[u]); } return ret; } intmain(){ read(n), read(m); for (int i = 1, u, v; i <= m; i++) read(u), read(v), addedge(u, v); returnMCS(), printf("%d\n", Color()), 0; }