#include <bits/stdc++.h>
using namespace std;
char *fs, *ft, buf[1 << 15];
inline char getc() {
  return (fs == ft &&
          (ft = (fs = buf) + fread(buf, 1, 1 << 15, stdin), fs == ft))
             ? 0
             : *fs++;
}
inline int read() {
  int x = 0, f = 1;
  char ch = getc();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getc();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getc();
  }
  return x * f;
}
const int MAXN = 100010;
int n, m, len;
int vis[MAXN], q[MAXN], mark[MAXN], t, ans = -1;
int lin[MAXN], ver[MAXN << 1], nex[MAXN << 1];
set<int> s;
set<int>::iterator it;
inline void add(int x, int y) {
  ver[++len] = y;
  nex[len] = lin[x];
  lin[x] = len;
}
inline void dfs(int x) {
  it = s.begin();
  while (it != s.end()) {
    if (vis[*it]) {
      ++it;
      continue;
    }
    q[++t] = *it;
    mark[*it] = 1;
    s.erase(it++);
  }
}
int main() {
  n = read();
  m = read();
  for (int i = 1; i <= m; ++i) {
    int x, y;
    x = read();
    y = read();
    add(x, y);
    add(y, x);
  }
  for (int i = 2; i <= n; ++i) s.insert(i);
  for (int i = 1; i <= n; ++i) {
    if (mark[i]) continue;
    ++ans;
    q[++t] = i;
    s.erase(i);
    int h = 1;
    mark[i] = 1;
    while (h <= t) {
      for (int j = lin[q[h]]; j; j = nex[j]) vis[ver[j]] = 1;
      dfs(q[h]);
      for (int j = lin[q[h]]; j; j = nex[j]) vis[ver[j]] = 0;
      ++h;
    }
  }
  printf("%d\n", ans);
  return 0;
}
