/*
Problem: 1243D
Date: 21-01-2024 07:36 PM
*/
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5 + 5;
int n, m, u, v;
set<int> adj[N];
int dsu[N];
int trace(int x) {
return dsu[x] < 0 ? x : dsu[x] = trace(dsu[x]);
}
void join(int x, int y) {
if((x = trace(x)) == (y = trace(y))) return;
if(dsu[x] > dsu[y]) swap(x, y);
dsu[x] += dsu[y];
dsu[y] = x;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
fill(dsu, dsu + n, -1);
for(int i = 0; i < m; i++) {
cin >> u >> v;
u--; v--;
adj[u].insert(v);
adj[v].insert(u);
}
int m = 0;
for(int i = 0; i < n; i++) {
if(adj[i].size() < adj[m].size()) m = i;
}
for(int i = 0; i < n; i++) {
if(adj[m].count(i) == 0) {
join(m, i);
}
}
for(int x : adj[m]) {
for(int i = 0; i < n; i++) {
if(adj[x].count(i) == 0) {
join(x, i);
}
}
}
int cnt = 0;
for(int i = 0; i < n; i++) {
if(dsu[i] < 0) cnt++;
}
cout << (cnt - 1) << endl;
}
235A - LCM Challenge | 1075B - Taxi drivers and Lyft |
1562A - The Miracle and the Sleeper | 1216A - Prefixes |
1490C - Sum of Cubes | 868A - Bark to Unlock |
873B - Balanced Substring | 1401D - Maximum Distributed Tree |
1716C - Robot in a Hallway | 1688B - Patchouli's Magical Talisman |
99A - Help Far Away Kingdom | 622B - The Time |
1688C - Manipulating History | 1169D - Good Triple |
1675B - Make It Increasing | 588A - Duff and Meat |
1541B - Pleasant Pairs | 1626B - Minor Reduction |
1680A - Minimums and Maximums | 1713A - Traveling Salesman Problem |
1713B - Optimal Reduction | 1710A - Color the Picture |
1686B - Odd Subarrays | 251A - Points on Line |
427C - Checkposts | 1159A - A pile of stones |
508A - Pasha and Pixels | 912A - Tricky Alchemy |
1249A - Yet Another Dividing into Teams | 1713C - Build Permutation |