#include <bits/stdc++.h>
using namespace std;
const int N = 200001;
int nxt[N], lst[N], n, m, vis[N], bl[N];
int first[N], nx[N * 2], point[N * 2], e = 0;
void add_edge(int x, int y) {
  nx[e] = first[x];
  first[x] = e;
  point[e++] = y;
}
void del(int pos) {
  nxt[lst[pos]] = nxt[pos];
  lst[nxt[pos]] = lst[pos];
}
queue<int> q;
int main() {
  int ans = -1;
  scanf("%d%d", &n, &m);
  memset(first, -1, sizeof(first));
  memset(nxt, -1, sizeof(nxt));
  for (int i = 1; i <= m; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    add_edge(x, y);
    add_edge(y, x);
  }
  for (int i = 0; i <= n; i++) nxt[i] = i + 1, lst[i] = i - 1;
  while (nxt[0] != n + 1) {
    ans++;
    int F = nxt[0];
    del(F);
    q.push(F);
    vis[F] = 1;
    while (!q.empty()) {
      int now = q.front();
      q.pop();
      int p = nxt[0];
      while (p != n + 1) bl[p] = 0, p = nxt[p];
      for (int i = first[now]; ~i; i = nx[i]) {
        int pos = point[i];
        if (vis[pos]) continue;
        bl[pos] = 1;
      }
      p = nxt[0];
      while (p != n + 1) {
        if (!bl[p]) vis[p] = 1, q.push(p), del(p);
        p = nxt[p];
      }
    }
  }
  cout << ans << endl;
  return 0;
}
