#include <bits/stdc++.h>
using u32 = uint32_t;
using u64 = uint64_t;
using i32 = int32_t;
using i64 = int64_t;
const u64 infty = std::numeric_limits<u64>::max();
void DFS(std::vector<std::unordered_map<u32, u32>>& g, u32 src,
         std::set<u32>& uv, std::vector<bool>& vis) {
  vis[src] = true;
  std::vector<u32> uv2;
  uv2.reserve(uv.size());
  for (auto it = uv.begin(); it != uv.end();) {
    if (vis[*it] == false && g[src].count(*it) == 0) {
      uv2.push_back(*it);
      uv.erase(it++);
    } else {
      ++it;
    }
  }
  for (u32 i = 0; i < uv2.size(); ++i) {
    DFS(g, uv2[i], uv, vis);
  }
}
int main() {
  std::ios_base::sync_with_stdio(0);
  u64 n, m;
  std::cin >> n >> m;
  if (m == 0) {
    std::cout << "0\n";
    return 0;
  }
  std::vector<std::unordered_map<u32, u32>> g(n);
  for (u64 i = 0; i < m; i++) {
    u32 a, b;
    std::cin >> a >> b;
    --a;
    --b;
    g[a][b] = 1;
    g[b][a] = 1;
  }
  u64 ans = 0;
  std::set<u32> uv;
  for (u64 i = 0; i < n; ++i) {
    uv.insert(i);
  }
  std::vector<bool> vis(n, false);
  for (u64 i = 0; i < n; ++i) {
    if (vis[i] == false) {
      DFS(g, i, uv, vis);
      ans++;
    }
  }
  std::cout << (ans - 1) << "\n";
  return 0;
}
