#include <bits/stdc++.h>
#pragma optimize("O3")
using namespace std;
const long long MOD = 1e9 + 7;
const long long INF = 1e9 + 7;
const int base = 2e5 + 1;
const int MAX = 1e5 + 2;
const double EPS = 1e-9;
const double PI = acos(-1.);
const int MAXN = 1e5 + 7;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
vector<set<int>> g(MAXN);
set<int> is;
void dfs(int v) {
  int x = -1;
  is.erase(v);
  while (true) {
    auto it = is.upper_bound(x);
    if (it == is.end()) break;
    x = *it;
    if (!g[v].count(x) && is.count(x)) {
      dfs(x);
    }
  }
}
int main() {
  int n, m;
  cin >> n >> m;
  for (long long i = (0); i < (m); ++i) {
    int v, u;
    cin >> v >> u;
    u--;
    v--;
    g[u].insert(v);
    g[v].insert(u);
  }
  for (long long i = (0); i < (n); ++i) is.insert(i);
  int k = 0;
  for (long long i = (0); i < (n); ++i) {
    if (is.count(i)) {
      k++;
      dfs(i);
    }
  }
  cout << k - 1;
  return 0;
}
