#include <bits/stdc++.h>
using namespace std;
int n, m;
const int MX = 1000 * 100 + 99;
vector<int> E[MX];
set<int> reached;
set<int> not_reached;
vector<int> todo_reached = {1};
vector<pair<int, int> > bad_E_todo;
void visit(int nova) {
  if (reached.find(nova) != reached.end()) return;
  reached.insert(nova);
  not_reached.erase(nova);
  todo_reached.push_back(nova);
  for (int j = 1; j < (int)E[nova].size() - 1; j++) {
    bad_E_todo.push_back({nova, E[nova][j]});
  }
}
int solve() {
  for (int i = 1; i <= n; i++) {
    not_reached.insert(i);
  }
  visit(1);
  int result = 0;
  while (!not_reached.empty()) {
    ;
    if (!todo_reached.empty()) {
      int curr = todo_reached.back();
      todo_reached.pop_back();
      int sz = E[curr].size();
      for (int j = 0; j + 1 < sz; j++) {
        int L = E[curr][j] + 1, R = E[curr][j + 1] - 1;
        while (true) {
          ;
          auto it = not_reached.lower_bound(L);
          if (it != not_reached.end() && *it <= R) {
            int nova = *it;
            visit(nova);
          } else
            break;
        }
      }
    } else {
      auto bad_E = bad_E_todo.back();
      bad_E_todo.pop_back();
      int nova = bad_E.second;
      if (reached.find(nova) == reached.end()) {
        result++;
        visit(nova);
      }
    }
  }
  return result;
}
int main() {
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    int a, b;
    cin >> a >> b;
    E[a].push_back(b);
    E[b].push_back(a);
  }
  for (int i = 1; i <= n; i++) {
    E[i].push_back(0);
    E[i].push_back(n + 1);
    sort(E[i].begin(), E[i].end());
  }
  cout << solve();
  return 0;
}
