#include <bits/stdc++.h>
using namespace std;
struct Edge { int to, id; };
int N, M, K;
vector<vector<Edge>> g;
vector<int> tin, low, isBridge;
int timerDFS = 0;
void dfsBridge(int u, int pEdge) {
tin[u] = low[u] = ++timerDFS;
for (auto e : g[u]) {
if (e.id == pEdge) continue;
if (!tin[e.to]) {
dfsBridge(e.to, e.id);
low[u] = min(low[u], low[e.to]);
if (low[e.to] > tin[u]) isBridge[e.id] = 1;
} else low[u] = min(low[u], tin[e.to]);
}
}
vector<int> comp, compSize;
void dfsComp(int u, int c) {
comp[u] = c; compSize[c]++;
for (auto e : g[u]) if (comp[e.to] == -1 && !isBridge[e.id]) dfsComp(e.to, c);
}
vector<vector<int>> tree;
vector<int> subSize;
vector<bool> removed;
long long badPairs = 0;
int getSize(int u, int p) {
subSize[u] = compSize[u];
for (int v : tree[u]) if (v != p && !removed[v]) subSize[u] += getSize(v, u);
return subSize[u];
}
int getCentroid(int u, int p, int n) {
for (int v : tree[u]) if (v != p && !removed[v]) if (subSize[v] > n/2) return getCentroid(v, u, n);
return u;
}
void collect(int u, int p, int d, vector<pair<int,int>>& nodes) {
nodes.push_back({d, compSize[u]});
for (int v : tree[u]) if (v != p && !removed[v]) collect(v, u, d+1, nodes);
}
void solveCentroid(int c) {
vector<pair<int,int>> distAll;
distAll.push_back({0, compSize[c]});
for (int v : tree[c]) if (!removed[v]) {
vector<pair<int,int>> distSub;
collect(v, c, 1, distSub);
for (auto [da, ca] : distSub)
for (auto [db, cb] : distAll)
if (da + db < K) badPairs += 1LL * ca * cb;
distAll.insert(distAll.end(), distSub.begin(), distSub.end());
}
}
void decompose(int u) {
int n = getSize(u, -1);
int c = getCentroid(u, -1, n);
solveCentroid(c);
removed[c] = true;
for (int v : tree[c]) if (!removed[v]) decompose(v);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> N >> M >> K;
g.assign(N+1, {});
for (int i=1; i<=M; i++) {
int u,v; cin >> u >> v;
g[u].push_back({v,i});
g[v].push_back({u,i});
}
tin.assign(N+1,0); low.assign(N+1,0); isBridge.assign(M+1,0);
for (int i=1; i<=N; i++) if (!tin[i]) dfsBridge(i,-1);
comp.assign(N+1,-1);
int compCnt=0;
for (int i=1; i<=N; i++) if (comp[i]==-1) { compSize.push_back(0); dfsComp(i,compCnt++); }
tree.assign(compCnt,{});
for (int u=1; u<=N; u++) for (auto e:g[u]) if (isBridge[e.id]) {
int cu=comp[u], cv=comp[e.to];
if (cu!=cv) tree[cu].push_back(cv);
}
subSize.assign(compCnt,0);
removed.assign(compCnt,false);
long long total = accumulate(compSize.begin(),compSize.end(),0LL);
long long totalPairs = total*(total-1)/2;
decompose(0);
cout << totalPairs - badPairs << "\n";
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgpzdHJ1Y3QgRWRnZSB7IGludCB0bywgaWQ7IH07CmludCBOLCBNLCBLOwp2ZWN0b3I8dmVjdG9yPEVkZ2U+PiBnOwp2ZWN0b3I8aW50PiB0aW4sIGxvdywgaXNCcmlkZ2U7CmludCB0aW1lckRGUyA9IDA7Cgp2b2lkIGRmc0JyaWRnZShpbnQgdSwgaW50IHBFZGdlKSB7CiAgICB0aW5bdV0gPSBsb3dbdV0gPSArK3RpbWVyREZTOwogICAgZm9yIChhdXRvIGUgOiBnW3VdKSB7CiAgICAgICAgaWYgKGUuaWQgPT0gcEVkZ2UpIGNvbnRpbnVlOwogICAgICAgIGlmICghdGluW2UudG9dKSB7CiAgICAgICAgICAgIGRmc0JyaWRnZShlLnRvLCBlLmlkKTsKICAgICAgICAgICAgbG93W3VdID0gbWluKGxvd1t1XSwgbG93W2UudG9dKTsKICAgICAgICAgICAgaWYgKGxvd1tlLnRvXSA+IHRpblt1XSkgaXNCcmlkZ2VbZS5pZF0gPSAxOwogICAgICAgIH0gZWxzZSBsb3dbdV0gPSBtaW4obG93W3VdLCB0aW5bZS50b10pOwogICAgfQp9Cgp2ZWN0b3I8aW50PiBjb21wLCBjb21wU2l6ZTsKdm9pZCBkZnNDb21wKGludCB1LCBpbnQgYykgewogICAgY29tcFt1XSA9IGM7IGNvbXBTaXplW2NdKys7CiAgICBmb3IgKGF1dG8gZSA6IGdbdV0pIGlmIChjb21wW2UudG9dID09IC0xICYmICFpc0JyaWRnZVtlLmlkXSkgZGZzQ29tcChlLnRvLCBjKTsKfQoKdmVjdG9yPHZlY3RvcjxpbnQ+PiB0cmVlOwp2ZWN0b3I8aW50PiBzdWJTaXplOwp2ZWN0b3I8Ym9vbD4gcmVtb3ZlZDsKbG9uZyBsb25nIGJhZFBhaXJzID0gMDsKCmludCBnZXRTaXplKGludCB1LCBpbnQgcCkgewogICAgc3ViU2l6ZVt1XSA9IGNvbXBTaXplW3VdOwogICAgZm9yIChpbnQgdiA6IHRyZWVbdV0pIGlmICh2ICE9IHAgJiYgIXJlbW92ZWRbdl0pIHN1YlNpemVbdV0gKz0gZ2V0U2l6ZSh2LCB1KTsKICAgIHJldHVybiBzdWJTaXplW3VdOwp9CgppbnQgZ2V0Q2VudHJvaWQoaW50IHUsIGludCBwLCBpbnQgbikgewogICAgZm9yIChpbnQgdiA6IHRyZWVbdV0pIGlmICh2ICE9IHAgJiYgIXJlbW92ZWRbdl0pIGlmIChzdWJTaXplW3ZdID4gbi8yKSByZXR1cm4gZ2V0Q2VudHJvaWQodiwgdSwgbik7CiAgICByZXR1cm4gdTsKfQoKdm9pZCBjb2xsZWN0KGludCB1LCBpbnQgcCwgaW50IGQsIHZlY3RvcjxwYWlyPGludCxpbnQ+PiYgbm9kZXMpIHsKICAgIG5vZGVzLnB1c2hfYmFjayh7ZCwgY29tcFNpemVbdV19KTsKICAgIGZvciAoaW50IHYgOiB0cmVlW3VdKSBpZiAodiAhPSBwICYmICFyZW1vdmVkW3ZdKSBjb2xsZWN0KHYsIHUsIGQrMSwgbm9kZXMpOwp9Cgp2b2lkIHNvbHZlQ2VudHJvaWQoaW50IGMpIHsKICAgIHZlY3RvcjxwYWlyPGludCxpbnQ+PiBkaXN0QWxsOwogICAgZGlzdEFsbC5wdXNoX2JhY2soezAsIGNvbXBTaXplW2NdfSk7CiAgICBmb3IgKGludCB2IDogdHJlZVtjXSkgaWYgKCFyZW1vdmVkW3ZdKSB7CiAgICAgICAgdmVjdG9yPHBhaXI8aW50LGludD4+IGRpc3RTdWI7CiAgICAgICAgY29sbGVjdCh2LCBjLCAxLCBkaXN0U3ViKTsKICAgICAgICBmb3IgKGF1dG8gW2RhLCBjYV0gOiBkaXN0U3ViKQogICAgICAgICAgICBmb3IgKGF1dG8gW2RiLCBjYl0gOiBkaXN0QWxsKQogICAgICAgICAgICAgICAgaWYgKGRhICsgZGIgPCBLKSBiYWRQYWlycyArPSAxTEwgKiBjYSAqIGNiOwogICAgICAgIGRpc3RBbGwuaW5zZXJ0KGRpc3RBbGwuZW5kKCksIGRpc3RTdWIuYmVnaW4oKSwgZGlzdFN1Yi5lbmQoKSk7CiAgICB9Cn0KCnZvaWQgZGVjb21wb3NlKGludCB1KSB7CiAgICBpbnQgbiA9IGdldFNpemUodSwgLTEpOwogICAgaW50IGMgPSBnZXRDZW50cm9pZCh1LCAtMSwgbik7CiAgICBzb2x2ZUNlbnRyb2lkKGMpOwogICAgcmVtb3ZlZFtjXSA9IHRydWU7CiAgICBmb3IgKGludCB2IDogdHJlZVtjXSkgaWYgKCFyZW1vdmVkW3ZdKSBkZWNvbXBvc2Uodik7Cn0KCmludCBtYWluKCkgewogICAgaW9zOjpzeW5jX3dpdGhfc3RkaW8oZmFsc2UpOwogICAgY2luLnRpZShudWxscHRyKTsKCiAgICBjaW4gPj4gTiA+PiBNID4+IEs7CiAgICBnLmFzc2lnbihOKzEsIHt9KTsKICAgIGZvciAoaW50IGk9MTsgaTw9TTsgaSsrKSB7CiAgICAgICAgaW50IHUsdjsgY2luID4+IHUgPj4gdjsKICAgICAgICBnW3VdLnB1c2hfYmFjayh7dixpfSk7CiAgICAgICAgZ1t2XS5wdXNoX2JhY2soe3UsaX0pOwogICAgfQoKICAgIHRpbi5hc3NpZ24oTisxLDApOyBsb3cuYXNzaWduKE4rMSwwKTsgaXNCcmlkZ2UuYXNzaWduKE0rMSwwKTsKICAgIGZvciAoaW50IGk9MTsgaTw9TjsgaSsrKSBpZiAoIXRpbltpXSkgZGZzQnJpZGdlKGksLTEpOwoKICAgIGNvbXAuYXNzaWduKE4rMSwtMSk7CiAgICBpbnQgY29tcENudD0wOwogICAgZm9yIChpbnQgaT0xOyBpPD1OOyBpKyspIGlmIChjb21wW2ldPT0tMSkgeyBjb21wU2l6ZS5wdXNoX2JhY2soMCk7IGRmc0NvbXAoaSxjb21wQ250KyspOyB9CgogICAgdHJlZS5hc3NpZ24oY29tcENudCx7fSk7CiAgICBmb3IgKGludCB1PTE7IHU8PU47IHUrKykgZm9yIChhdXRvIGU6Z1t1XSkgaWYgKGlzQnJpZGdlW2UuaWRdKSB7CiAgICAgICAgaW50IGN1PWNvbXBbdV0sIGN2PWNvbXBbZS50b107CiAgICAgICAgaWYgKGN1IT1jdikgdHJlZVtjdV0ucHVzaF9iYWNrKGN2KTsKICAgIH0KCiAgICBzdWJTaXplLmFzc2lnbihjb21wQ250LDApOwogICAgcmVtb3ZlZC5hc3NpZ24oY29tcENudCxmYWxzZSk7CgogICAgbG9uZyBsb25nIHRvdGFsID0gYWNjdW11bGF0ZShjb21wU2l6ZS5iZWdpbigpLGNvbXBTaXplLmVuZCgpLDBMTCk7CiAgICBsb25nIGxvbmcgdG90YWxQYWlycyA9IHRvdGFsKih0b3RhbC0xKS8yOwogICAgZGVjb21wb3NlKDApOwogICAgY291dCA8PCB0b3RhbFBhaXJzIC0gYmFkUGFpcnMgPDwgIlxuIjsKfQo=