/*
  Copyright 2013,2016 Marek "p2004a" Rusinowski
  Computing MST - Kruskal's algorithm
*/
#include <cstdio>
#include <vector>
#include <algorithm>
#include <numeric>
#include <tuple>

using namespace std;

class FindUnion {
  vector<int> root, rank;

 public:
  FindUnion(int n) : root(n), rank(n) {
  	iota(root.begin(), root.end(), 0);
  }

  int find_set(int v) {
    if (root[v] == v) return v;
    root[v] = find_set(root[v]);
    return root[v];
  }

  void union_sets(int v, int u) {
    v = find_set(v);
    u = find_set(u);
    if (rank[v] < rank[u]) {
      root[v] = u;
    } else if (rank[v] > rank[u]) {
      root[u] = v;
    } else {
      root[v] = u;
      ++rank[v];
    }
  }
};

int main() {
  int n, m, a, b, c;
  vector<tuple<int, int, int>> out;
  scanf("%d %d", &n, &m);
  FindUnion fu(n);
  for (int i = 0; i < m; ++i) {
    scanf("%d %d %d", &a, &b, &c);
    out.emplace_back(c, --a, --b);
  }
  sort(out.begin(), out.end());
  for (auto t: out) {
    tie(c, a, b) = t;
    if (fu.find_set(a) != fu.find_set(b)) {
      fu.union_sets(a, b);
      printf("%d %d\n", a + 1, b + 1);
    }
  }
  return 0;
}
