#include <bits/stdc++.h>
using namespace std;
const long long int mod = 998244353;
long long int power(long long int x, long long int y) {
  if (y == 0) return 1;
  return ((y % 2 == 1 ? x : 1) * power(x * x, y / 2));
}
vector<long long int> primeNumbers;
void SieveOfEratosthenes(int n) {
  bool prime[n + 1];
  memset(prime, true, sizeof(prime));
  for (int p = 2; p * p <= n; p++) {
    if (prime[p] == true) {
      for (int i = p * p; i <= n; i += p) prime[i] = false;
    }
  }
  for (int p = 2; p <= n; p++) {
    if (prime[p]) {
      primeNumbers.push_back(p);
    }
  }
}
vector<vector<int> > v(100005);
int visit[100005];
void dfs(int index, int parent) {
  visit[index] = 1;
  for (int i = 0; i < v[parent].size(); i++) {
    int node = v[parent][i];
    if (visit[node])
      continue;
    else if (!binary_search(v[index].begin(), v[index].end(), node)) {
      visit[node] = 1;
      dfs(node, index);
    }
  }
}
void pre() {}
void solve() {
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    v[0].push_back(i);
  }
  for (int i = 0; i < m; i++) {
    int a, b;
    cin >> a >> b;
    v[a].push_back(b);
    v[b].push_back(a);
  }
  for (int i = 1; i <= n; i++) {
    sort(v[i].begin(), v[i].end());
  }
  int cnt = 0;
  for (int i = 1; i <= n; i++) {
    if (visit[i] == 0) {
      dfs(i, 0);
      cnt++;
    }
  }
  int ans = cnt - 1;
  cout << ans;
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int t;
  t = 1;
  pre();
  while (t--) {
    solve();
    if (t > 0) {
      cout << endl;
    }
  }
  cerr << "Time : " << (double)clock() / (double)CLOCKS_PER_SEC << "s\n";
  return 0;
}
