#include <bits/stdc++.h>
using namespace std;
map<pair<int, int>, int> mmap;
const int manx = 1e6 + 50;
char s1[manx], s2[manx];
set<int> se;
int vis[manx];
struct Edge {
  int to, next;
} edge[manx * 2];
int k, head[manx];
void add(int a, int b) {
  edge[k].to = b;
  edge[k].next = head[a];
  head[a] = k++;
}
queue<int> que;
int used[manx];
int main(int argc, char const *argv[]) {
  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) {
    head[i] = -1;
  }
  for (int i = 1; i <= m; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    add(a, b), add(b, a);
  }
  for (int i = 1; i <= n; i++) {
    se.insert(i);
  }
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    if (vis[i] == 0) {
      ans++;
      que.push(i);
      vis[i] = 1;
      se.erase(i);
      while (que.size()) {
        int u = que.front();
        que.pop();
        for (int i = head[u]; i != -1; i = edge[i].next) {
          used[edge[i].to] = 1;
        }
        set<int>::iterator it;
        for (it = se.begin(); it != se.end();) {
          int to = *it;
          it++;
          if (used[to] == 0) {
            que.push(to);
            se.erase(to);
            vis[to] = 1;
          }
        }
        for (int i = head[u]; i != -1; i = edge[i].next) {
          used[edge[i].to] = 0;
        }
      }
    }
  }
  printf("%d\n", ans - 1);
  return 0;
}
