#include <bits/stdc++.h>
using namespace std;
int uf[1000005];
int root(int x) { return (uf[x] < 0) ? x : (uf[x] = root(uf[x])); }
template <typename T>
void read(T &x) {
  x = 0;
  int f = 1;
  char c = getchar();
  for (; !isdigit(c); c = getchar())
    if (c == '-') f = -f;
  for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
  x *= f;
}
int in() {
  int x = 0, c;
  for (; (unsigned)((c = getchar()) - '0') >= 10;) {
    if (c == '-') return -in();
    if (!~c) throw ~0;
  }
  do {
    x = (x << 3) + (x << 1) + (c - '0');
  } while ((unsigned)((c = getchar()) - '0') < 10);
  return x;
}
bool conn(int x, int y) {
  x = root(x);
  y = root(y);
  if (x == y) return 0;
  if (uf[x] > uf[y]) swap(x, y);
  uf[x] += uf[y];
  uf[y] = x;
  return 1;
}
int n, m, k;
int C;
int main() {
  int i;
  int u, v;
  for (; ~scanf("%d%d%d", &n, &m, &k);) {
    memset(uf, ~0, sizeof(uf));
    for (int i = 0; i < m; i++) {
      u = in() - 1;
      v = in() - 1;
      conn(u, v);
    }
    C = 0;
    priority_queue<int, vector<int>, greater<int> > q;
    int sum = 0;
    for (u = 0; u < n; u++) {
      if (uf[u] < 0) {
        ++C;
        q.push(-uf[u]);
        sum += min(-uf[u], k);
      }
    }
    int ans = 0;
    for (;;) {
      if (sum >= 2 * (C - 1)) {
        break;
      }
      int a = q.top();
      q.pop();
      sum -= min(a, k);
      int b = q.top();
      q.pop();
      sum -= min(b, k);
      q.push(a + b);
      sum += min(a + b, k);
      --C;
      ++ans;
    }
    cout << ans;
  }
  return 0;
}
