#include<bits/stdc++.h> #define LL long long using namespace std; LL ans; const int maxn = 100010; int n,m,k,tot,C; inline int read(){int x;scanf("%d",&x);return x;} int first[maxn],to[maxn],next[maxn],cnt; int root,sum; int f[maxn],size[maxn],vis[maxn]; int q[maxn],dis[maxn],inq[maxn],inc[maxn],top; inline void insert(int u,int v) { to[++cnt] = v; next[cnt] = first[u]; first[u] = cnt; } namespace Fenwick_Tree { int c[maxn]; inline int lowbit(int x){return x & (-x);} inline int query(int x) { if(x<1)return 0; int ret = 0; for(int i=x;i;i-=lowbit(i))ret += c[i]; return ret; } inline void add(int x,int val) { tot += val; for(int i=x;i<=2*C+n;i+=lowbit(i))c[i] += val; } } using namespace Fenwick_Tree; namespace DFZ { inline void getrt(int x,int fa) { f[x] = 0;size[x] = 1; for(int i=first[x];i;i=next[i]) { if(to[i] == fa || vis[to[i]])continue; getrt(to[i],x); size[x] += size[to[i]]; f[x] = max(f[x],size[to[i]]); } f[x] = max(f[x],sum - size[x]); if(f[x] < f[root]) root = x; } inline void dfs(int x,int fa) { q[++top] = dis[x]; for(int i=first[x];i;i=next[i]) { if(to[i] == fa || vis[to[i]])continue; dis[to[i]] = dis[x] + 1; dfs(to[i],x); } } inline void solve(int x) { vis[x] = 1; for(int i=first[x];i;i=next[i]) if(!vis[to[i]]) { dis[to[i]] = 1; dfs(to[i],x); for(int j=1;j<=top;j++) { if(q[j] + 1 >= k)ans++; ans += tot - query(k - q[j] - 2); } while(top) add(q[top--],1); } for(int i=first[x];i;i=next[i]) if(!vis[to[i]]) { dfs(to[i],x); while(top)add(q[top--],-1); } for(int i=first[x];i;i=next[i]) if(!vis[to[i]] && size[to[i]] >= k) { root = 0;sum = size[to[i]]; getrt(to[i],x); solve(root); } } inline void mian(int x) { sum = n; f[0] = 1e9; root = 0; getrt(x,0); solve(root); } } int INC,delta; using namespace DFZ; namespace inccle { inline void getinc(int x,int fa) { if(INC) return; q[++top] = x , inq[x] = 1; for(int i=first[x];i;i=next[i]) { if(to[i] == fa)continue; if(inq[to[i]]) { while(q[top] != to[i])inc[++INC] = q[top--]; inc[++INC] = to[i]; } else getinc(to[i],x); } top--,inc[x] = 0; } void solveinc() { getinc(1,0);top=0; C=INC;delta=2*C; for(int i=1;i<=C;i++)inc[i+C]=inc[i]; for(int i=1;i<=C;i++)vis[inc[i]]=1; for(int i=1;i<=C;i++) { vis[inc[i]]=0; mian(inc[i]); vis[inc[i]]=1; } for(int i=1;i<=n;i++)vis[i]=0; for(int i=1;i<=C;i++)vis[inc[i]]=1; for(int i=1;i<=2*C;i++) { if(i>C) { vis[inc[i-C]]=0;dfs(inc[i-C],0);vis[inc[i-C]]=1; for(int j=1;j<=top;j++)add(q[j]+delta+C,-1); for(int j=1;j<=top;j++) ans+=tot-query(k+delta-q[j]); top=0; } dis[inc[i]]=1; vis[inc[i]]=0;dfs(inc[i],0);vis[inc[i]]=1; while(top)add(q[top--]+delta,1);delta--; } } } using namespace inccle; int main() { n=read();m=read();k=read(); for(int i=1;i<=m;i++) { int u=read(),v=read(); insert(u,v); } if(n==m)solveinc(); else mian(1); printf("%lld\n",ans); return 0; }