#include <bits/stdc++.h>
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
mt19937_64 rng_64(chrono::steady_clock::now().time_since_epoch().count());
const double PI = 2 * acos(0.0);
const string DIGITS = "0123456789";
const string ALPH = "abcdefghijklmnopqrstuvwxyz";
istream &operator>>(istream &in, pair<int, int> &a) {
  in >> a.first >> a.second;
  return in;
}
ostream &operator<<(ostream &out, pair<int, int> &a) {
  out << a.first << ' ' << a.second;
  return out;
}
istream &operator>>(istream &in, pair<long double, long double> &a) {
  in >> a.first >> a.second;
  return in;
}
ostream &operator<<(ostream &out, pair<long double, long double> &a) {
  out << a.first << ' ' << a.second;
  return out;
}
template <class T0, class T1>
inline ostream &operator<<(ostream &out, pair<T0, T1> &a) {
  return out << "{" << a.first << ", " << a.second << "}";
}
template <class T0, class T1, class T2>
inline ostream &operator<<(ostream &out, tuple<T0, T1, T2> &a) {
  return out << "{" << get<0>(a) << ", " << get<1>(a) << ", " << get<2>(a)
             << "}";
}
template <class T0, class T1, class T2, class T3>
inline ostream &operator<<(ostream &out, tuple<T0, T1, T2, T3> &a) {
  return out << "{" << get<0>(a) << ", " << get<1>(a) << ", " << get<2>(a)
             << ", " << get<3>(a) << "}";
}
template <class T>
inline ostream &operator<<(ostream &out, vector<T> &a) {
  out << "[";
  for (int i = 0; i < int(a.size()); ++i)
    out << a[i] << vector<string>{", ", "]  "}[i + 1 == a.size()];
  return out;
}
void print(vector<int> kek, int k) {
  ofstream cout("output.txt");
  cout << ((int)((kek).size())) << ' ' << k << '\n';
  for (auto p : kek) {
    cout << p << ' ';
  }
  cout.close();
  exit(0);
}
void smain();
signed main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cout << setprecision(12) << fixed;
  smain();
}
const int M1 = 1000000093, p1 = 27162;
const int M2 = 1000000087, p2 = 241;
const long double pi = atan2l(1, 0) * 2, EPS = 1e-8, PEPS = 1e-7;
const int N = 2e5 + 100, B = 400, M = 1e9 + 7, K = 110, psze = 30,
          oo = 1e9 + 100;
set<int> vertices[N];
set<int> flex;
int used[N];
void dfs(int v, int col) {
  used[v] = col;
  flex.erase(v);
  int l = 0;
  vector<int> to;
  for (auto c : flex) {
    if (used[c] || vertices[v].count(c)) continue;
    to.push_back(c);
  }
  for (int v : to) flex.erase(v);
  for (int v : to) dfs(v, col);
}
void smain() {
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < m; ++i) {
    int a, b;
    cin >> a >> b;
    vertices[a].insert(b);
    vertices[b].insert(a);
  }
  for (int i = 1; i <= n; ++i) flex.insert(i);
  int cur = 1;
  for (int i = 1; i <= n; ++i)
    if (!used[i]) dfs(i, cur++);
  set<int> ans;
  for (int i = 1; i < N; ++i)
    if (used[i]) ans.insert(used[i]);
  cout << ((int)((ans).size())) - 1;
}
