#include <bits/stdc++.h>
using namespace std;
using ll = int64_t;
using ull = uint64_t;
using ii = pair<int, int>;
using pii = pair<int, int>;
using vi = vector<int>;
template <typename T1, typename T2>
string print_iterable(T1 begin_iter, T2 end_iter, int counter) {
  bool done_something = false;
  stringstream res;
  res << "[";
  for (; begin_iter != end_iter and counter; ++begin_iter) {
    done_something = true;
    counter--;
    res << *begin_iter << ", ";
  }
  string str = res.str();
  if (done_something) {
    str.pop_back();
    str.pop_back();
  }
  str += "]";
  return str;
}
vector<int> SortIndex(int size, std::function<bool(int, int)> compare) {
  vector<int> ord(size);
  for (int i = 0; i < size; i++) ord[i] = i;
  sort(ord.begin(), ord.end(), compare);
  return ord;
}
template <typename T>
bool MinPlace(T& a, const T& b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T>
bool MaxPlace(T& a, const T& b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename S, typename T>
ostream& operator<<(ostream& out, const pair<S, T>& p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}
template <typename T>
ostream& operator<<(ostream& out, const vector<T>& v) {
  out << "[";
  for (int i = 0; i < (int)v.size(); i++) {
    out << v[i];
    if (i != (int)v.size() - 1) out << ", ";
  }
  out << "]";
  return out;
}
template <class TH>
void _dbg(const char* name, TH val) {
  clog << name << ": " << val << endl;
}
template <class TH, class... TA>
void _dbg(const char* names, TH curr_val, TA... vals) {
  while (*names != ',') clog << *names++;
  clog << ": " << curr_val << ", ";
  _dbg(names + 1, vals...);
}
struct RollbackUF {
  vi e;
  vector<pii> st;
  RollbackUF(int n) : e(n, -1) {}
  int size(int x) { return -e[find(x)]; }
  int find(int x) { return e[x] < 0 ? x : find(e[x]); }
  int time() { return ((int)((st).size())); }
  void rollback(int t) {
    for (int i = time(); i-- > t;) e[st[i].first] = st[i].second;
    st.resize(t);
  }
  bool join(int a, int b) {
    a = find(a), b = find(b);
    if (a == b) return false;
    if (e[a] > e[b]) swap(a, b);
    st.push_back({a, e[a]});
    st.push_back({b, e[b]});
    e[a] += e[b];
    e[b] = a;
    return true;
  }
};
struct Edge {
  int a, b;
  ll w;
};
struct Node {
  Edge key;
  Node *l, *r;
  ll delta;
  void prop() {
    key.w += delta;
    if (l) l->delta += delta;
    if (r) r->delta += delta;
    delta = 0;
  }
  Edge top() {
    prop();
    return key;
  }
};
Node* merge(Node* a, Node* b) {
  if (!a || !b) return a ?: b;
  a->prop(), b->prop();
  if (a->key.w > b->key.w) swap(a, b);
  swap(a->l, (a->r = merge(b, a->r)));
  return a;
}
void pop(Node*& a) {
  a->prop();
  a = merge(a->l, a->r);
}
pair<ll, vi> dmst(int n, int r, vector<Edge>& g) {
  RollbackUF uf(n);
  vector<Node*> heap(n);
  for (Edge e : g) heap[e.b] = merge(heap[e.b], new Node{e});
  ll res = 0;
  vi seen(n, -1), path(n), par(n);
  seen[r] = r;
  vector<Edge> Q(n), in(n, {-1, -1}), comp;
  deque<tuple<int, int, vector<Edge>>> cycs;
  for (int s = 0; s < (n); ++s) {
    int u = s, qi = 0, w;
    while (seen[u] < 0) {
      if (!heap[u]) return {-1, {}};
      Edge e = heap[u]->top();
      heap[u]->delta -= e.w, pop(heap[u]);
      Q[qi] = e, path[qi++] = u, seen[u] = s;
      res += e.w, u = uf.find(e.a);
      if (seen[u] == s) {
        Node* cyc = 0;
        int end = qi, time = uf.time();
        do cyc = merge(cyc, heap[w = path[--qi]]);
        while (uf.join(u, w));
        u = uf.find(u), heap[u] = cyc, seen[u] = -1;
        cycs.push_front({u, time, {&Q[qi], &Q[end]}});
      }
    }
    for (int i = 0; i < (qi); ++i) in[uf.find(Q[i].b)] = Q[i];
  }
  for (auto& [u, t, comp] : cycs) {
    uf.rollback(t);
    Edge inEdge = in[u];
    for (auto& e : comp) in[uf.find(e.b)] = e;
    in[uf.find(inEdge.b)] = inEdge;
  }
  for (int i = 0; i < (n); ++i) par[i] = in[i].a;
  return {res, par};
}
struct segm {
  int a, b;
  ll w;
  bool operator<(segm a) const { return w < a.w; }
};
struct node {
  node* parent;
  ll rango;
  ll val;
};
vector<segm> V;
vector<node*> uds;
node* MakeSet(ll v) {
  node* a = (node*)malloc(sizeof(node));
  a->parent = a;
  a->rango = 0;
  a->val = v;
  return a;
}
node* findSet(int a) {
  node* s = uds[a];
  if (s == s->parent) {
    return s->parent;
  }
  s->parent = findSet(s->parent->val);
  return s->parent;
}
bool merge(int a, int b) {
  node* na = findSet(a);
  node* nb = findSet(b);
  if (na == nb) return false;
  if (na->rango > nb->rango) {
    na->rango += nb->rango;
    nb->parent = na->parent;
  } else {
    nb->rango += na->rango;
    na->parent = nb->parent;
  }
  return true;
}
const int MAXM = 2e5 + 100;
int v[MAXM];
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin.exceptions(cin.failbit);
  int t;
  cin >> t;
  while (t--) {
    V.clear();
    uds.clear();
    int n, k, m;
    cin >> n >> m >> k;
    V.reserve(m);
    uds.reserve(n);
    for (int i = 0; i < n; i++) uds.push_back(MakeSet(i));
    int tot = 0;
    int best = 1e9;
    segm bsegm;
    for (int i = 0; i < m; i++) {
      int a, b, w;
      cin >> a >> b >> w;
      a--;
      b--;
      if (abs(w - k) < best) {
        best = abs(w - k);
        bsegm.a = a;
        bsegm.b = b;
        bsegm.w = w;
      }
      V.push_back({a, b, w});
    }
    sort(V.begin(), V.end());
    ll cost = 0;
    merge(bsegm.a, bsegm.b);
    cost += best;
    for (int i = 0; i < m; i++) {
      if (merge(V[i].a, V[i].b)) {
        if (V[i].w > k) cost += V[i].w - k;
      }
    }
    cout << cost << '\n';
  }
  return 0;
}
