#include <bits/stdc++.h>
using namespace std;
struct E {
  int a, b, c, no;
  bool operator<(const E& x) const { return c < x.c; }
} b[400010], t[400010];
struct edge {
  int n, t, v;
} e[400010];
int n, m, tp, head[200010], ecnt, fa[200010], w[200010], cnt, dfn[200010],
    node[200010], siz[200010], top[200010], dep[200010], s[200010 << 2],
    mx[200010 << 2], ans[400010];
bool tag[400010];
inline void add(int a, int b, int c) {
  e[++ecnt] = (edge){head[a], b, c}, head[a] = ecnt,
  e[++ecnt] = (edge){head[b], a, c}, head[b] = ecnt;
}
inline int find(int x) {
  while (x ^ fa[x]) x = fa[x] = fa[fa[x]];
  return x;
}
inline void build(int x, int l, int r) {
  s[x] = 0x3f3f3f3f;
  if (l == r) {
    mx[x] = w[node[l]];
    return;
  }
  int mid = l + r >> 1;
  build(x << 1, l, mid), build(x << 1 | 1, mid + 1, r);
  mx[x] = max(mx[x << 1], mx[x << 1 | 1]);
}
inline int query(int x, int l, int r, int L, int R) {
  if (l == L && r == R) return mx[x];
  int mid = L + R >> 1;
  if (r <= mid)
    return query(x << 1, l, r, L, mid);
  else if (l > mid)
    return query(x << 1 | 1, l, r, mid + 1, R);
  return max(query(x << 1, l, mid, L, mid),
             query(x << 1 | 1, mid + 1, r, mid + 1, R));
}
inline void upd(int x, int l, int r, int L, int R, int v) {
  if (l == L && r == R) {
    s[x] = min(s[x], v);
    return;
  }
  int mid = L + R >> 1;
  if (r <= mid)
    upd(x << 1, l, r, L, mid, v);
  else if (l > mid)
    upd(x << 1 | 1, l, r, mid + 1, R, v);
  else
    upd(x << 1, l, mid, L, mid, v), upd(x << 1 | 1, mid + 1, r, mid + 1, R, v);
}
inline int ask(int x, int p, int l, int r) {
  if (l == r) return s[x];
  int mid = l + r >> 1;
  if (p <= mid) return min(s[x], ask(x << 1, p, l, mid));
  return min(s[x], ask(x << 1 | 1, p, mid + 1, r));
}
inline void dfs(int x, int p) {
  siz[x] = 1;
  for (int i = head[x]; i; i = e[i].n)
    if (e[i].t ^ p)
      fa[e[i].t] = x, dep[e[i].t] = dep[x] + 1, dfs(e[i].t, x),
      siz[x] += siz[e[i].t];
}
inline void dfs2(int x, int p) {
  dfn[x] = ++cnt, node[cnt] = x;
  int mx = -1, pos = -1, val;
  for (int i = head[x]; i; i = e[i].n)
    if (e[i].t != p && mx < siz[e[i].t]) mx = siz[pos = e[i].t], val = e[i].v;
  if (mx >= 0) top[pos] = top[x], w[pos] = val, dfs2(pos, x);
  for (int i = head[x]; i; i = e[i].n)
    if (e[i].t != p && e[i].t != pos)
      top[e[i].t] = e[i].t, w[e[i].t] = e[i].v, dfs2(e[i].t, x);
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) fa[i] = i;
  for (int i = 1; i <= m; i++)
    scanf("%d%d%d", &b[i].a, &b[i].b, &b[i].c), b[i].no = i;
  sort(b + 1, b + 1 + m);
  for (int i = 1; i <= m; i++) {
    int x = find(b[i].a), y = find(b[i].b);
    if (x ^ y)
      fa[x] = y, add(b[i].a, b[i].b, b[i].c), tag[b[i].no] = 1;
    else
      t[++tp] = b[i];
  }
  for (int i = 1; i <= n; i++)
    if (!siz[i]) fa[i] = 0, dfs(i, 0), dfs2(i, 0);
  build(1, 1, n);
  for (int i = 1; i <= tp; i++) {
    int x = t[i].a, y = t[i].b, mx = 0;
    while (top[x] ^ top[y]) {
      if (dep[top[x]] < dep[top[y]]) x ^= y ^= x ^= y;
      upd(1, dfn[top[x]], dfn[x], 1, n, t[i].c - 1);
      mx = max(mx, query(1, dfn[top[x]], dfn[x], 1, n));
      x = fa[top[x]];
    }
    if (x ^ y) {
      if (dep[x] < dep[y]) x ^= y ^= x ^= y;
      upd(1, dfn[y] + 1, dfn[x], 1, n, t[i].c - 1);
      mx = max(mx, query(1, dfn[y] + 1, dfn[x], 1, n));
    }
    ans[t[i].no] = mx - 1;
  }
  for (int i = 1; i <= m; i++) {
    int x = b[i].no, tmp;
    if (tag[x])
      tmp = ask(1, max(dfn[b[i].a], dfn[b[i].b]), 1, n),
      ans[x] = tmp == 0x3f3f3f3f ? -1 : tmp;
  }
  for (int i = 1; i <= m; i++) printf("%d ", ans[i]);
  return 0;
}
