#include<bits/stdc++.h>
using namespace std;
struct edge{int from,to,t;};

#define MAX_N 100005

typedef long long ll;

struct UF{
  int group;
  
  int par[MAX_N];
  int flg[MAX_N];
  int size[MAX_N];
  ll dat[MAX_N];
  
  void init(int n){
    group=n;
    for(int i=0;i<MAX_N;i++){
      par[i]=i;
      flg[i]=0;
      size[i]=1;
      dat[i]=0;
    }
  }
  
  int find(int x){
    if(x==par[x])return x;
    return find(par[x]);
  }
  
  bool same(int x,int y){
    return find(x)==find(y);
  }
  
  void unite(int x,int y,int tim=0){
    x=find(x);
    y=find(y);
    if(x==y)return;

    
    group--;
    if(size[x]<size[y])swap(x,y);
    
    par[y]=x;

    dat[y]+= (ll)(tim-flg[y])*size[y];
    
    dat[x]+= (ll)(tim-flg[x])*size[x];

    dat[y]-= dat[x];
    
    flg[x]=tim;

    size[x]+=size[y];
  }
  
  int getSize(int x){
    x=find(x);
    return size[x];
  }
  
  ll getSize(int x,int tim){
    ll res=0;
    while( x!=par[x]){
      res+=dat[x];
      x=par[x];
    }
    res+= (ll)(tim-flg[x])*size[x] + dat[x];
    return res;
  }
};

int N,M,T;
vector<edge> E[MAX_N];
vector<edge> G[MAX_N];
vector<int> g[MAX_N];
map<int,int> h[MAX_N];

UF tree;

int d[MAX_N];

int main(){
  scanf("%d %d %d",&N,&M,&T);
  for(int i=0;i<M;i++){
    int a,b,t;
    scanf("%d %d %d",&a,&b,&t);
    a--,b--;
    G[a].push_back( (edge){a,b,t} );
    G[b].push_back( (edge){b,a,t} );
    E[t].push_back((edge){a,b,t});
  }
  

  
  queue<int> Q;
  Q.push(0);
  memset(d,-1,sizeof(d));
  d[0]=0;
  while(!Q.empty()){
    int pos=Q.front();Q.pop();
    g[ d[pos] ].push_back(pos);
    for(int i=0;i<(int)G[pos].size();i++){
      edge e=G[pos][i];
      if(d[e.to]!=-1)continue;
      if(e.t<=d[pos])continue;
      d[e.to]=d[pos]+1;
      Q.push(e.to);
    }
  }

  
  tree.init(N);
  for(int i=100000;i>=T;i--){
    for(int j=0;j<(int)E[i].size();j++){
      tree.unite(E[i][j].from,E[i][j].to , 0 );
    }
  }
  

  
  for(int i=T-1;i>=0;i--){
    for(int j=0;j<(int)E[i].size();j++){
      tree.unite(E[i][j].from,E[i][j].to , T-i );
    }
  }

  //  for(int v=0;v<N;v++)
  //    cout<<v<<' '<<tree.flg[v]<<' '<<tree.size[v]<<' '<<tree.dat[v]<<endl;
  
  ll maxm=0;
  for(int i=0;i<N;i++){
    if(d[i]==-1||d[i]>T)continue;
    
    ll count=tree.getSize(i,T);
    //cout<<i<<' '<<count<<endl;
    maxm=max(maxm,count);
  }
  
  cout<<maxm<<endl;
  return 0;
}