#include <bits/stdc++.h>
using namespace std;
const long long inf = (long long)2e9;
const long long md = 1000000007;
long long dx[] = {1, -1, 0, 0}, dy[] = {0, 0, 1, -1};
long long power(long long a, long long p, long long md) {
  long long ans = 1;
  while (p) {
    if (p & 1) ans *= a;
    p /= 2;
    a *= a;
    ans %= md;
    a %= md;
  }
  return ans;
}
long long mdinv(long long a) { return power(a, md - 2, md); }
const long long nn = 100005;
class DSU {
 public:
  vector<long long> p, rank, len;
  DSU(long long n) {
    p.assign(n, 0);
    rank = p;
    len = p;
    for (long long i = 0; i < (long long)n; i++) p[i] = i, len[i] = 1;
  }
  long long findSet(long long i) {
    return (p[i] == i) ? i : p[i] = findSet(p[i]);
  }
  long long setSize(long long i) {
    i = findSet(i);
    return len[i];
  }
  bool merge(long long first, long long second) {
    first = findSet(first);
    second = findSet(second);
    if (first == second) return 0;
    if (rank[first] < rank[second]) swap(first, second);
    p[second] = first;
    len[first] += len[second];
    if (rank[first] == rank[second]) rank[first]++;
    return 1;
  }
};
vector<long long> adj[nn], adw[nn];
long long vis[nn];
set<pair<long long, long long>> bMST;
const long long LOG = 18;
long long lvl[nn], pr[nn][1 + LOG], prW[nn][1 + LOG];
void dfs(long long u, long long level, long long parent, long long wt) {
  vis[u] = 1;
  lvl[u] = level;
  pr[u][0] = parent;
  prW[u][0] = wt;
  for (long long i = 1; i <= LOG; i++) {
    long long v = pr[u][i - 1];
    if (v == -1) break;
    pr[u][i] = pr[v][i - 1];
    prW[u][i] = max(prW[u][i - 1], prW[v][i - 1]);
  }
  for (long long i = 0; i < (long long)(long long)(adj[u].size()); i++) {
    long long v = adj[u][i], w = adw[u][i];
    if (!vis[v]) {
      dfs(v, level + 1, u, w);
    }
  }
}
long long cusDis(long long a, long long b) {
  long long ansA = 0, ansB = 0;
  if (lvl[a] < lvl[b]) swap(a, b);
  long long diffH = lvl[a] - lvl[b];
  for (long long i = 0; i <= LOG; i++) {
    if ((diffH >> i) & 1) {
      ansA = max(ansA, prW[a][i]);
      a = pr[a][i];
    }
  }
  if (a == b) return ansA;
  for (long long i = LOG; i >= 0; i--) {
    if (pr[a][i] != pr[b][i]) {
      ansA = max(ansA, prW[a][i]);
      ansB = max(ansB, prW[b][i]);
      a = pr[a][i];
      b = pr[b][i];
    }
  }
  ansA = max(ansA, prW[a][0]);
  ansB = max(ansB, prW[b][0]);
  a = pr[a][0];
  b = pr[b][0];
  return max(ansA, ansB);
}
signed main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  long long n, m;
  cin >> n >> m;
  long long a, b, w;
  vector<tuple<long long, long long, long long>> edj, edjAct;
  for (long long i = 0; i < (long long)m; i++) {
    cin >> a >> b >> w;
    a--, b--;
    edj.push_back(make_tuple(w, a, b));
  }
  edjAct = edj;
  sort((edj).begin(), (edj).end());
  DSU dsu(n);
  for (long long i = 0; i < (long long)m; i++) {
    w = get<0>(edj[i]);
    a = get<1>(edj[i]);
    b = get<2>(edj[i]);
    if (dsu.merge(a, b)) {
      adj[a].push_back(b);
      adw[a].push_back(w);
      adj[b].push_back(a);
      adw[b].push_back(w);
      bMST.insert({min(a, b), max(a, b)});
    }
  }
  for (long long u = 0; u < (long long)n; u++) {
    for (long long i = 0; i < (long long)LOG + 1; i++) {
      pr[u][i] = -1;
      prW[u][i] = 0;
    }
  }
  dfs(0, 0, -1, 0);
  for (long long i = 0; i < (long long)(long long)(edjAct.size()); i++) {
    a = get<1>(edjAct[i]);
    b = get<2>(edjAct[i]);
    if (a > b) swap(a, b);
    if (bMST.count({a, b})) continue;
    cout << cusDis(a, b) << " ";
  }
}
