#include <bits/stdc++.h>
using namespace std;
const int MAXN = (int)2e5 + 7;
vector<int> G[MAXN];
int pic[1007][1007], vis[MAXN], siz[MAXN];
unordered_map<int, int> mp;
int tot, val[MAXN];
int fa[MAXN], sz;
int findfa(int x) {
  if (x == fa[x]) return x;
  return fa[x] = findfa(fa[x]);
}
void unite(int x, int y, bool flag = 1) {
  int u = findfa(x), v = findfa(y);
  if (u == v) return;
  fa[u] = v;
  if (flag) siz[v] += siz[u];
  sz++;
}
int main() {
  int N, M;
  scanf("%d %d", &N, &M);
  for (int i = (int)1; i <= (int)N; i++) fa[i] = i, siz[i] = 1;
  for (int i = (int)1; i <= (int)M; i++) {
    int u, v;
    scanf("%d %d", &u, &v);
    G[u].push_back(v);
    G[v].push_back(u);
  }
  int mn = 1e9, id = 0;
  for (int i = (int)1; i <= (int)N; i++) {
    if (G[i].size() < mn) {
      mn = G[i].size();
      id = i;
    }
  }
  for (int v : G[id]) vis[v] = 1;
  vis[id] = 1;
  for (int i = (int)1; i <= (int)N; i++)
    if (vis[i] == 0) unite(id, i);
  for (int i = (int)1; i <= (int)N; i++) {
    if (findfa(i) == i) {
      mp[i] = ++tot;
      val[tot] = i;
    }
  }
  for (int u = (int)1; u <= (int)N; u++) {
    for (int v : G[u]) {
      int f1 = mp[findfa(u)];
      int f2 = mp[findfa(v)];
      if (f1 == f2) continue;
      pic[f1][f2]++;
    }
  }
  for (int i = (int)1; i <= (int)tot; i++) {
    for (int j = (int)i + 1; j <= (int)tot; j++) {
      if (1LL * siz[val[i]] * siz[val[j]] != pic[i][j]) {
        unite(val[i], val[j], 0);
      }
    }
  }
  int ans = N - sz - 1;
  printf("%d\n", ans);
}
