#include <cmath>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <queue>
#define rep(i, l, r) for(int i = l; i <= r; i++)
#define down(i, l, r) for(int i = l; i >= r; i--)
#define MS 12345
#define MAX 1037471823
#define Q 103
using namespace std;
int n, m, k[MS], r[MS], l[MS], next[MS], last[MS], h[MS], s[MS], a, now;
bool b[MS];
struct node
{
int x, y;
bool operator < (const node &k) const { return x < k.x || (x == k.x && y < k.y); }
} c[2345678];
int main()
{
scanf("%d%d", &n, &m);
rep(i, 1, m) scanf("%d%d", &c[i].x, &c[i].y);
rep(i, 1, m) c[i+m].x = c[i].y, c[i+m].y = c[i].x; m *= 2;
sort(c+1, c+1+m); c[m+1].x = MAX;
rep(i, 2, m) if (c[i].x == c[i-1].x && c[i].y == c[i-1].y) c[i] = c[m+1];
sort(c+1, c+1+m); while (c[m].x == MAX) m--;
k[1] = 1; rep(i, 2, n+1) { k[i] = k[i-1]; while (c[k[i]].x < i) k[i]++; }
h[0] = n; rep(i, 2, n) next[i] = i-1; rep(i, 1, n-1) last[i] = i+1; now = 0;
down(i, n, 1)
{
l[i] = h[now]; b[l[i]] = true; h[now] = next[h[now]]; if (h[now] != 0) last[h[now]] = 0;
while (h[now] == 0 && now > 0) now--;
rep(j, k[l[i]], k[l[i]+1]-1) if (b[c[j].y] == false)
{
a = c[j].y;
if (a != h[r[a]]) next[last[a]] = next[a], last[next[a]] = last[a]; else h[r[a]] = next[a], last[next[a]] = 0;
r[a]++;
if (r[a] > now) now = r[a];
next[a] = h[r[a]]; last[h[r[a]]] = a; h[r[a]] = a; last[a] = 0;
}
}
now = 0;
down(i, n, 1)
{
rep(j, 1, now) b[j] = false;
rep(j, k[l[i]], k[l[i]+1]-1) b[s[c[j].y]] = true;
a = 0;
down(j, now, 1) if (b[j] == false) a = j;
if (a == 0) now++, s[l[i]] = now; else s[l[i]] = a;
}
printf("%d\n", now);
return 0;
}
I2luY2x1ZGUgPGNtYXRoPgojaW5jbHVkZSA8Y3N0cmluZz4KI2luY2x1ZGUgPGNzdGRpbz4KI2luY2x1ZGUgPGNzdGRsaWI+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPGZzdHJlYW0+CiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDxxdWV1ZT4KCiNkZWZpbmUgcmVwKGksIGwsIHIpIGZvcihpbnQgaSA9IGw7IGkgPD0gcjsgaSsrKQojZGVmaW5lIGRvd24oaSwgbCwgcikgZm9yKGludCBpID0gbDsgaSA+PSByOyBpLS0pCiNkZWZpbmUgTVMgMTIzNDUKI2RlZmluZSBNQVggMTAzNzQ3MTgyMwojZGVmaW5lIFEgMTAzCgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKaW50IG4sIG0sIGtbTVNdLCByW01TXSwgbFtNU10sIG5leHRbTVNdLCBsYXN0W01TXSwgaFtNU10sIHNbTVNdLCBhLCBub3c7CmJvb2wgYltNU107CnN0cnVjdCBub2RlCnsKCWludCB4LCB5OwoJYm9vbCBvcGVyYXRvciA8IChjb25zdCBub2RlICZrKSBjb25zdCB7IHJldHVybiB4IDwgay54IHx8ICh4ID09IGsueCAmJiB5IDwgay55KTsgfQp9IGNbMjM0NTY3OF07CgppbnQgbWFpbigpCnsKCXNjYW5mKCIlZCVkIiwgJm4sICZtKTsKCXJlcChpLCAxLCBtKSBzY2FuZigiJWQlZCIsICZjW2ldLngsICZjW2ldLnkpOwoJcmVwKGksIDEsIG0pIGNbaSttXS54ID0gY1tpXS55LCBjW2krbV0ueSA9IGNbaV0ueDsgbSAqPSAyOwoJc29ydChjKzEsIGMrMSttKTsgY1ttKzFdLnggPSBNQVg7CglyZXAoaSwgMiwgbSkgaWYgKGNbaV0ueCA9PSBjW2ktMV0ueCAmJiBjW2ldLnkgPT0gY1tpLTFdLnkpIGNbaV0gPSBjW20rMV07Cglzb3J0KGMrMSwgYysxK20pOyB3aGlsZSAoY1ttXS54ID09IE1BWCkgbS0tOwoJa1sxXSA9IDE7IHJlcChpLCAyLCBuKzEpIHsga1tpXSA9IGtbaS0xXTsgd2hpbGUgKGNba1tpXV0ueCA8IGkpIGtbaV0rKzsgfQoJCgloWzBdID0gbjsgcmVwKGksIDIsIG4pIG5leHRbaV0gPSBpLTE7IHJlcChpLCAxLCBuLTEpIGxhc3RbaV0gPSBpKzE7IG5vdyA9IDA7Cglkb3duKGksIG4sIDEpCgl7CgkJbFtpXSA9IGhbbm93XTsgYltsW2ldXSA9IHRydWU7IGhbbm93XSA9IG5leHRbaFtub3ddXTsgaWYgKGhbbm93XSAhPSAwKSBsYXN0W2hbbm93XV0gPSAwOwoJCXdoaWxlIChoW25vd10gPT0gMCAmJiBub3cgPiAwKSBub3ctLTsKCQlyZXAoaiwga1tsW2ldXSwga1tsW2ldKzFdLTEpIGlmIChiW2Nbal0ueV0gPT0gZmFsc2UpIAoJCXsKCQkJYSA9IGNbal0ueTsKCQkJaWYgKGEgIT0gaFtyW2FdXSkgbmV4dFtsYXN0W2FdXSA9IG5leHRbYV0sIGxhc3RbbmV4dFthXV0gPSBsYXN0W2FdOyBlbHNlIGhbclthXV0gPSBuZXh0W2FdLCBsYXN0W25leHRbYV1dID0gMDsKCQkJclthXSsrOyAKCQkJaWYgKHJbYV0gPiBub3cpIG5vdyA9IHJbYV07CgkJCW5leHRbYV0gPSBoW3JbYV1dOyBsYXN0W2hbclthXV1dID0gYTsgaFtyW2FdXSA9IGE7IGxhc3RbYV0gPSAwOwoJCX0KCX0KCQoJbm93ID0gMDsKCWRvd24oaSwgbiwgMSkgCgl7CgkJcmVwKGosIDEsIG5vdykgYltqXSA9IGZhbHNlOwoJCXJlcChqLCBrW2xbaV1dLCBrW2xbaV0rMV0tMSkgYltzW2Nbal0ueV1dID0gdHJ1ZTsgCgkJYSA9IDA7CgkJZG93bihqLCBub3csIDEpIGlmIChiW2pdID09IGZhbHNlKSBhID0gajsKCQlpZiAoYSA9PSAwKSBub3crKywgc1tsW2ldXSA9IG5vdzsgZWxzZSBzW2xbaV1dID0gYTsKCX0KCXByaW50ZigiJWRcbiIsIG5vdyk7CglyZXR1cm4gMDsKfQo=