fun readInts() = readLine()!!.split(" ").map(String::toInt)

const val P = 1000000007L

data class FiniteField(val x: Long) {
  operator fun plus(o: FiniteField) = FiniteField((x + o.x) % P)
  operator fun plus(o: Int) = this + FiniteField(o.toLong())
  operator fun minus(o: FiniteField) = FiniteField((x + P - o.x) % P)
  operator fun minus(o: Int) = this - FiniteField(o.toLong())
  operator fun times(o: FiniteField) = FiniteField((x * o.x) % P)
  operator fun times(o: Int) = this * FiniteField(o.toLong())
}

fun pow2(p: Int): FiniteField {
  if (p == 0) return FiniteField(1L)
  val x = pow2(p / 2)
  return if (p % 2 == 0) x * x else x * x * 2
}

data class Edge(val v1: Int, val v2: Int, val w: Long, val id: Int)

// Union-Find Set.
class UFSet(n: Int) {
  private var ranks = IntArray(n, { 1 })
  private var prevs = IntArray(n, { it })

  // Returns a root of a tree which x belongs to.
  fun find(x: Int): Int {
    if (x != prevs[x]) prevs[x] = find(prevs[x])
    return prevs[x]
  }

  // Merges a set which x belongs to and a set which y belongs to.
  fun union(x: Int, y: Int) {
    val xRoot = find(x)
    val yRoot = find(y)
    when {
      ranks[xRoot] > ranks[yRoot] -> prevs[yRoot] = prevs[xRoot]
      ranks[xRoot] < ranks[yRoot] -> prevs[xRoot] = prevs[yRoot]
      prevs[xRoot] != prevs[yRoot] -> {
        prevs[yRoot] = prevs[xRoot]
        ranks[xRoot]++
      }
    }
  }
}

fun makeMST(n: Int, e: Edge, edges: Array<Edge>): Long {
  val ufSet = UFSet(n)
  var totalW = 0L
  ufSet.union(e.v1, e.v2)
  totalW += e.w
  for (e in edges) {
    if (ufSet.find(e.v1) == ufSet.find(e.v2)) continue
    ufSet.union(e.v1, e.v2)
    totalW += e.w
  }
  return totalW
}

fun main(args: Array<String>) {
  val (n, m) = readInts()
  val x = readLine()!!.toLong()
  val edges = Array(m, {
    val (uRaw, vRaw, w) = readInts()
    Edge(uRaw - 1, vRaw - 1, w.toLong(), it)
  })
  edges.sortWith(java.util.Comparator { e1, e2 -> java.lang.Long.compare(e1.w, e2.w) })
  val mstCosts = edges.map { makeMST(n, it, edges) }

  fun countEdges(w: Long): Int {
    return mstCosts.count { it <= w }
  }

  fun countColorings(w: Long): FiniteField {
    val numEdges = countEdges(w)
    if (numEdges == 0) return pow2(m)
    return pow2(m - numEdges) * 2
  }

  val ans = countColorings(x - 1) - countColorings(x)
  println(ans.x)
}
