// 求连通分量的个数
#include <string.h>
#include <iostream>
#include <set>
using std::cout;
using std::cin;
using std::endl;
using std::set;
bool visited[1000] = {false};
set<int> graph[1000];
void DFS(int i) {
visited[i] = true;
for (auto elem : graph[i]) {
if (!visited[elem])
DFS(elem);
}
}
void ClearGraph(int n) {
for (int i = 1; i <= n; ++i) {
graph[i].clear();
}
}
int main() {
int n, m;
int t1, t2; // 两个镇子之间有一条路
while (cin >> n >> m) {
for (int i = 1; i <= m; ++i) {
scanf("%d%d", &t1, &t2);
graph[t1].insert(t2);
graph[t2].insert(t1);
}
int count = 0;
for (int i = 1; i <= n; ++i) {
if (!visited[i]) {
// DFS次数就是连通分量个数
DFS(i);
count++;
}
}
cout << count - 1 << endl; // 连通分量个数-1就是需要再铺建的道路的数量
memset(visited, false, sizeof(visited));
ClearGraph(n);
}
return 0;
}