1 #include<iostream>
2 #include<set>
3 #include<map>
4 #include<queue>
5 #include<algorithm>
6 using namespace std;
7
8 const int maxn = 100010;
9 int n, m;
10 set<int>e[maxn];
11 set<int>node;
12 int fa[maxn];
13 int sz[maxn];
14
15 int find(int x)
16 {
17 if (fa[x] == x) return x;
18 fa[x] = find(fa[x]);
19 return fa[x];
20 }
21
22 void merge(int a, int b)
23 {
24 int fx = find(a);
25 int fy = find(b);
26 fa[fx] = find(fy);
27 sz[fy] += sz[fx];
28 }
29
30 bool check(int a, int b)
31 {
32 return find(a) == find(b);
33 }
34
35 void dfs(int x)
36 {
37 set<int>reach;
38 for (auto it : node)
39 {
40 if (e[x].find(it) == e[x].end())
41 {
42 reach.insert(it);
43 }
44 }
45 for (auto it : reach)
46 {
47 node.erase(it);
48 }
49 for (auto it : reach)
50 {
51 dfs(it);
52 }
53 }
54
55 int main()
56 {
57 cin >> n >> m;
58 for (int i = 1; i <= n; i++)
59 {
60 fa[i] = i;
61 node.insert(i);
62 }
63 for (int i = 1; i <= m; i++)
64 {
65 int a, b;
66 cin >> a >> b;
67 e[a].insert(b);
68 e[b].insert(a);
69 }
70 /*
71 //dfs做法
72 int ans = 0;
73 for (int i = 1; i <= n; i++)
74 {
75 if (node.find(i) != node.end())
76 {
77 dfs(i);
78 ans++;
79 }
80 }
81 */
82 //正解:并查集
83 vector<int>g;
84 for (int i = 1; i <= n; i++)
85 {
86 sz[i] = 1;
87 map<int, int>cnt;
88 for (auto it : e[i])
89 {
90 if (it >= i) continue;
91 cnt[find(it)]++;
92 }
93 for (auto it : g)
94 {
95 int t = find(it);
96 if (check(i, t)) continue;
97 if (sz[t] > cnt[t])
98 {
99 merge(i, t);
100 }
101 }
102 int fi = find(i);
103 if (fi == i) g.push_back(fi);
104 }
105 int ans = 0;
106 for (int i = 1; i <= n; i++)
107 {
108 if (fa[i] == i) ans++;
109 }
110 cout << ans - 1;
111 return 0;
112 }
113