#include <bits/stdc++.h>
using namespace std;
using LL = long long int;
const int maxn = 2e5 + 5;
int n = 0, m = 0, k = 0, ans = 0;
struct node {
  int u, v, cost;
  node(int u_ = 0, int v_ = 0, int cost_ = 0) : u(u_), v(v_), cost(cost_) {}
};
struct cmp {
  bool operator()(const node& a, const node& b) { return a.cost > b.cost; }
};
priority_queue<node, vector<node>, cmp> pq;
node e[maxn];
struct UnionSet {
  int *set, maxsize;
  UnionSet(int init_Capacity) : maxsize(init_Capacity) {
    set = new int[maxsize];
    memset(set, -1, sizeof(int) * maxsize);
  }
  void Union(int x, int y) {
    int root1 = findRoot(x);
    int root2 = findRoot(y);
    if (root1 == root2) return;
    if (set[root1] <= set[root2]) {
      set[root1] += set[root2];
      set[root2] = root1;
    } else {
      set[root2] += set[root1];
      set[root1] = root2;
    }
    return;
  }
  int findRoot(int x) {
    if (set[x] < 0) return x;
    return set[x] = findRoot(set[x]);
  }
  ~UnionSet() { delete[] set; }
};
LL getMst() {
  LL ans = 0;
  int cnt = 0;
  UnionSet s(n + 5);
  while (cnt < n - 1 && !pq.empty()) {
    node t = pq.top();
    pq.pop();
    if (s.findRoot(t.u) != s.findRoot(t.v)) {
      ++cnt;
      s.Union(t.u, t.v);
      ans += max(0, t.cost - k);
    }
  }
  return ans;
}
int main(void) {
  int T = 0;
  scanf("%d", &T);
  for (int cas = 1; cas <= T; ++cas) {
    while (!pq.empty()) pq.pop();
    scanf("%d %d %d", &n, &m, &k);
    for (int i = 0; i < m; ++i) {
      scanf("%d %d %d", &e[i].u, &e[i].v, &e[i].cost);
      pq.push(e[i]);
    }
    LL ans = getMst();
    if (ans == 0) {
      ans = 0x3f3f3f3f3f3f3f3fL;
      for (int i = 0; i < m; ++i) ans = min(ans, (LL)abs(e[i].cost - k));
    }
    printf("%d\n", ans);
  }
  return 0;
}
