#include <bits/stdc++.h>
using namespace std;
const signed int inf = (signed)(~0u >> 1);
const signed int llf = (signed int)(~0ull >> 1);
template <typename T>
inline void readInteger(T& u) {
  static char x;
  while (!isdigit(x = getchar()))
    ;
  for (u = x - '0'; isdigit(x = getchar()); u = u * 10 + x - '0')
    ;
}
template <typename T>
class Matrix {
 public:
  T* p;
  int row;
  int col;
  Matrix() : p(NULL) {}
  Matrix(int row, int col) : row(row), col(col) { p = new T[(row * col)]; }
  T* operator[](int pos) { return p + (pos * col); }
};
typedef class Edge {
 public:
  int u;
  int v;
  int w;
  bool seced;
  int rid;
  Edge(int u = 0, int v = 0, int w = 0) : u(u), v(v), w(w), seced(false) {}
  bool operator<(Edge b) const { return w < b.w; }
} Edge;
typedef class Node {
 public:
  int val;
  Node* nxt[2];
  Node(int val = inf) : val(val) { nxt[0] = nxt[1] = NULL; }
} Node;
typedef pair<Node*, Node*> pnn;
Node pool[2000000];
Node* top = pool;
Node* newnode(int x) {
  if (top == pool + 2000000) return new Node(x);
  *top = Node(x);
  return top++;
}
Node* merge(Node*& l, Node* r) {
  if (l == NULL) return r;
  if (r == NULL) return l;
  if (l->val > r->val) swap(l, r);
  int p = rand() % 2;
  l->nxt[p] = merge(l->nxt[p], r);
  return l;
}
int n, m;
Edge* edge;
int* res;
int* ans;
inline void init() {
  readInteger(n);
  readInteger(m);
  edge = new Edge[(m + 1)];
  for (int i = 1; i <= m; i++) {
    readInteger(edge[i].u);
    readInteger(edge[i].v);
    readInteger(edge[i].w);
    edge[i].rid = i;
  }
}
int* f;
int find(int x) { return (f[x] != x) ? (f[x] = find(f[x])) : (x); }
vector<int>* g;
vector<int>* add;
vector<int>* del;
inline void Kruskal() {
  f = new int[(n + 1)];
  g = new vector<int>[(n + 1)];
  for (int i = 1; i <= n; i++) f[i] = i;
  sort(edge + 1, edge + m + 1);
  int fin = 0;
  for (int i = 1; i <= m && fin < n - 1; i++) {
    if (find(edge[i].u) != find(edge[i].v)) {
      f[find(edge[i].u)] = find(edge[i].v);
      g[edge[i].u].push_back(i);
      g[edge[i].v].push_back(i);
      edge[i].seced = true;
      fin++;
    }
  }
}
const int BZMAX = 18;
int* dep;
Matrix<int> bz;
Matrix<int> bzm;
void dfs1(int node, int fa, int lastv) {
  dep[node] = dep[fa] + 1;
  bz[node][0] = fa;
  bzm[node][0] = lastv;
  for (int i = 1; i < BZMAX; i++)
    bz[node][i] = bz[bz[node][i - 1]][i - 1],
    bzm[node][i] = max(bzm[node][i - 1], bzm[bz[node][i - 1]][i - 1]);
  for (int i = 0; i < (signed)g[node].size(); i++) {
    if (!edge[g[node][i]].seced) continue;
    int e = (edge[g[node][i]].u == node) ? (edge[g[node][i]].v)
                                         : (edge[g[node][i]].u);
    if (e == fa) continue;
    dfs1(e, node, edge[g[node][i]].w);
  }
}
pair<int, int> lca(int u, int v) {
  if (dep[u] < dep[v]) swap(u, v);
  int rtmax = 0;
  int ca = dep[u] - dep[v];
  for (int i = 0; i < BZMAX; i++)
    if (ca & (1 << i)) {
      rtmax = max(rtmax, bzm[u][i]);
      u = bz[u][i];
    }
  if (u == v) return pair<int, int>(u, rtmax);
  for (int i = BZMAX - 1; ~i; i--) {
    if (bz[u][i] != bz[v][i]) {
      rtmax = max(rtmax, bzm[u][i]);
      rtmax = max(rtmax, bzm[v][i]);
      u = bz[u][i];
      v = bz[v][i];
    }
  }
  rtmax = max(rtmax, bzm[u][0]);
  rtmax = max(rtmax, bzm[v][0]);
  return pair<int, int>(bz[u][0], rtmax);
}
pair<Node*, Node*> dfs2(int node, int fa, int tofa) {
  Node* rt = NULL;
  Node* dl = NULL;
  for (int i = 0; i < (signed)g[node].size(); i++) {
    if (!edge[g[node][i]].seced) continue;
    int e = (edge[g[node][i]].u == node) ? (edge[g[node][i]].v)
                                         : (edge[g[node][i]].u);
    if (e == fa) continue;
    pnn ap = dfs2(e, node, g[node][i]);
    rt = merge(rt, ap.first);
    dl = merge(dl, ap.second);
  }
  for (int i = 0; i < (signed)add[node].size(); i++)
    rt = merge(rt, newnode(add[node][i]));
  for (int i = 0; i < (signed)del[node].size(); i++)
    dl = merge(dl, newnode(del[node][i]));
  while (dl && rt->val == dl->val) {
    rt = merge(rt->nxt[0], rt->nxt[1]);
    rt = merge(rt->nxt[0], rt->nxt[1]);
    dl = merge(dl->nxt[0], dl->nxt[1]);
  }
  res[tofa] = (!rt) ? (-1) : (rt->val);
  return pnn(rt, dl);
}
inline void solve() {
  res = new int[(m + 1)];
  dep = new int[(n + 1)];
  bz = Matrix<int>(n + 1, BZMAX);
  bzm = Matrix<int>(n + 1, BZMAX);
  dep[0] = 0;
  for (int i = 0; i < BZMAX; i++) bz[0][i] = bzm[0][i] = 0;
  dfs1(1, 0, 0);
  add = new vector<int>[(n + 1)];
  del = new vector<int>[(n + 1)];
  for (int i = 1; i <= m; i++) {
    if (edge[i].seced) {
      res[i] = -2;
      continue;
    }
    int u = edge[i].u, v = edge[i].v;
    pair<int, int> l = lca(u, v);
    res[i] = l.second;
  }
  ans = new int[(m + 1)];
  for (int i = 1; i <= m; i++) ans[edge[i].rid] = res[i];
  for (int i = 1; i <= m; i++) {
    if (ans[i] != -2) {
      printf("%d\n", (ans[i] != -1) ? (ans[i]) : (1000000000));
    }
  }
}
int main() {
  srand(233);
  init();
  Kruskal();
  solve();
  return 0;
}
