#include <bits/stdc++.h>
#pragma warning(disable : 4996)
#pragma comment(linker, "/STACK:336777216")
using namespace std;
int IT_MAX = 1 << 17;
long long MOD = 1000000007;
const int INF = 0x3f3f3f3f;
const long long LL_INF = 0x3f3f3f3f3f3f3f3f;
const double PI = acos(-1);
const double ERR = 1e-10;
set<pair<int, int> > Sx;
vector<int> conn[200050];
bool pchk[200050];
int lc = 1;
vector<int> Vl[200050];
int r[200050];
int sz[200050];
int root(int x) { return (x == r[x]) ? x : (r[x] = root(r[x])); }
int main() {
  int N, M, i, j;
  scanf("%d %d", &N, &M);
  for (i = 1; i <= M; i++) {
    int t1, t2;
    scanf("%d %d", &t1, &t2);
    Sx.emplace(t1, t2);
    Sx.emplace(t2, t1);
    conn[t1].push_back(t2);
    conn[t2].push_back(t1);
  }
  int p = 1;
  for (i = 2; i <= N; i++)
    if (conn[i].size() < conn[p].size()) p = i;
  for (auto it : conn[p]) pchk[it] = true;
  for (i = 1; i <= N; i++)
    if (!pchk[i]) Vl[1].push_back(i);
  for (i = 1; i <= N; i++) {
    if (!pchk[i]) continue;
    lc++;
    Vl[lc].push_back(i);
  }
  for (i = 1; i <= lc; i++) r[i] = i;
  for (i = 1; i <= lc; i++) {
    for (j = i + 1; j <= lc; j++) {
      bool chk = false;
      for (auto it1 : Vl[i]) {
        for (auto it2 : Vl[j]) {
          if (Sx.count(pair<int, int>(it1, it2))) continue;
          chk = true;
          break;
        }
      }
      if (chk) r[root(i)] = root(j);
    }
  }
  int cnt = 0;
  for (i = 1; i <= lc; i++) sz[root(i)] += Vl[i].size();
  vector<int> Va;
  for (i = 1; i <= lc; i++)
    if (r[i] == i) Va.push_back(sz[i]);
  sort((Va).begin(), (Va).end());
  printf("%d\n", (int)Va.size() - 1);
}
