#include <iostream>
#include <vector>
#include<algorithm>
#include<iomanip>
#include<queue>
#include<map>
#include<bitset>
#include<math.h>
using namespace std;
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define REP(i,m,n) for(int i=m;i<(int)(n);i++)
typedef pair<int,int> pint;
typedef pair<long long,pint> p3;
typedef long long ll;
const int inf   = 1e9+7;
const ll  longinf = 1LL<<60;
const int mod=1e9+7;
int dx[4]={1,0,-1,0}, dy[4]={0,1,0,-1};

struct UnionFind{
  int par[1010];
  UnionFind(int n){
    rep(i,n)par[i]=i;
    }
  int find(int n){
    if(par[n]==n)return n;
    return par[n]=find(par[n]);
    }
  void unite(int x,int y){
    x=par[x];
    y=par[y];
    par[x]=y;
    }
  };


int main(){
  int n,m;
  cin>>n>>m;
  ll xx;cin>>xx;
  ll ma[n];
  rep(i,n)ma[i]=0;
  p3 v[m];
  rep(i,m){
    int x,y;
    ll w;
    cin>>x>>y>>w;
    x--;y--;
    v[i]={w,{x,y}};
    }
  sort(v,v+m);
  int cnt1=m,cnt2=m;
  rep(j,m){
    ll ret=0;
    UnionFind uf(n);
    uf.unite(v[j].second.first,v[j].second.second);
    ret+=v[j].first;
  rep(i,m){
    int from=v[i].second.first,to=v[i].second.second;
    ll cost=v[i].first;
    if(uf.find(from)==uf.find(to))continue;
    uf.unite(from,to);
    ret+=cost;
    }
    if(ret<xx)cnt1--;
    if(ret<=xx)cnt2--;
    }
  ll ans1=1,ans2=1;
  rep(i,cnt1)ans1=2*ans1 %mod;
  rep(i,cnt2)ans2=2*ans2 %mod;
  if(cnt1!=m)ans1=2*ans1%mod;
  if(cnt2!=m)ans2=2*ans2%mod;
  cout<<(ans1-ans2+mod)%mod<<endl;
  return 0;         
  }