/*
  Copyright 2012 Marek "p2004a" Rusinowski
  Computing MST - Prim's algorithm
*/
#include <cstdio>
#include <set>
#include <vector>
#include <algorithm>

#define MAXN 1000000
#define INF 0x7FFFFFFF

std::vector<std::pair<int, int> > edges[MAXN], out;
int d[MAXN], p[MAXN];

struct cmp {
  bool operator() (int a, int b) {
    if (d[a] < d[b]) {
      return true;
    } else if (d[a] > d[b]) {
      return false;
    } else {
      return a < b;
    }
  }
};

void mst(int n) {
  std::set<int, cmp> q;
  std::fill(d + 1, d + n, INF);
  q.insert(0);
  while (!q.empty()) {
    int v = *(q.begin());
    q.erase(q.begin());
    if (v != 0) {
      out.push_back(std::make_pair(p[v], v));
    }
    for (int i = 0; i < (int) edges[v].size(); ++i) {
      if (d[edges[v][i].first] > d[v] + edges[v][i].second) {
        q.erase(edges[v][i].first);
        d[edges[v][i].first] = d[v] + edges[v][i].second;
        p[edges[v][i].first] = v;
        q.insert(edges[v][i].first);
      }
    }
  }
}

int main() {
  int n, m, a, b, c;
  scanf("%d %d", &n, &m);
  for (int i = 0; i < m; ++i) {
    scanf("%d %d %d", &a, &b, &c);
    --a, --b;
    edges[a].push_back(std::make_pair(b, c));
    edges[b].push_back(std::make_pair(a, c));
  }
  mst(n);
  for (int i = 0; i < (int) out.size(); ++i) {
    printf("%d %d\n", out[i].first + 1, out[i].second + 1);
  }
  return 0;
}
