#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
const int inf = 0x77777777;
struct lq {
  int fro;
  int to;
  int nxt;
  int val;
  int id;
} node[N << 1], edge[N << 1];
int etot, n, m;
int head[N], tot;
int mst;
int used[N];
int fa[N], son[N], size[N], top[N], d[N];
int tree[N], pre[N], num;
int a[N];
int fat[N];
int minn[N << 3];
int maxn[N << 3];
int lazy[N << 3];
bool cmp(const lq &a, const lq &b) { return a.val < b.val; }
bool mmp(const lq &a, const lq &b) { return a.id < b.id; }
void add(int u, int v, int val) {
  node[++tot].nxt = head[u];
  node[tot].fro = u;
  node[tot].to = v;
  node[tot].val = val;
  head[u] = tot;
}
void addd(int u, int v, int val, int id) {
  edge[++etot].fro = u;
  edge[etot].to = v;
  edge[etot].val = val;
  edge[etot].id = id;
}
inline int read() {
  int x = 0, w = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') w = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * w;
}
void dfs1(int x) {
  d[x] = d[fa[x]] + 1;
  size[x] = 1;
  for (int i = head[x]; i; i = node[i].nxt) {
    int v = node[i].to;
    if (v == fa[x]) continue;
    fa[v] = x;
    a[v] = node[i].val;
    dfs1(v);
    size[x] += size[v];
    if (size[son[x]] < size[v]) son[x] = v;
  }
}
void dfs2(int x, int y) {
  top[x] = y;
  tree[x] = ++num;
  pre[num] = x;
  if (son[x]) dfs2(son[x], y);
  for (int i = head[x]; i; i = node[i].nxt) {
    int v = node[i].to;
    if (v == fa[x] || v == son[x]) continue;
    dfs2(v, v);
  }
}
void update(int now) { maxn[now] = max(maxn[now << 1], maxn[now << 1 | 1]); }
void pushdown(int now) {
  if (lazy[now] == inf) return;
  lazy[now << 1] = min(lazy[now << 1], lazy[now]);
  lazy[now << 1 | 1] = min(lazy[now << 1 | 1], lazy[now]);
  minn[now << 1] = min(minn[now << 1], lazy[now]);
  minn[now << 1 | 1] = min(minn[now << 1 | 1], lazy[now]);
  lazy[now] = inf;
}
void build(int now, int l, int r) {
  if (l == r) {
    maxn[now] = a[pre[l]];
    return;
  }
  int mid = (l + r) >> 1;
  build(now << 1, l, mid);
  build(now << 1 | 1, mid + 1, r);
  update(now);
}
int querymax(int now, int l, int r, int cl, int cr) {
  int ans = -inf;
  if (l > cr || r < cl) return -inf;
  if (l >= cl && r <= cr) {
    return maxn[now];
  }
  int mid = (l + r) >> 1;
  ans = max(ans, querymax(now << 1, l, mid, cl, cr));
  ans = max(ans, querymax(now << 1 | 1, mid + 1, r, cl, cr));
  return ans;
}
int querymin(int now, int l, int r, int x) {
  int ans = inf;
  if (l > x || r < x) return inf;
  if (l == r) {
    return minn[now];
  }
  pushdown(now);
  int mid = (l + r) >> 1;
  ans = min(ans, querymin(now << 1, l, mid, x));
  ans = min(ans, querymin(now << 1 | 1, mid + 1, r, x));
  return ans;
}
void qumin(int now, int l, int r, int cl, int cr, int k) {
  if (l > cr || r < cl) return;
  if (l >= cl && r <= cr) {
    minn[now] = min(minn[now], k);
    lazy[now] = min(lazy[now], k);
    return;
  }
  int mid = (l + r) >> 1;
  pushdown(now);
  qumin(now << 1, l, mid, cl, cr, k);
  qumin(now << 1 | 1, mid + 1, r, cl, cr, k);
  minn[now] = min(minn[now << 1], minn[now << 1 | 1]);
}
void getqumin(int x, int y, int val) {
  while (top[x] != top[y]) {
    qumin(1, 1, n, tree[top[x]], tree[x], val);
    x = fa[top[x]];
  }
  qumin(1, 1, n, tree[y] + 1, tree[x], val);
}
int getmax(int x, int y) {
  int ans = -inf;
  while (top[x] != top[y]) {
    ans = max(ans, querymax(1, 1, n, tree[top[x]], tree[x]));
    x = fa[top[x]];
  }
  ans = max(ans, querymax(1, 1, n, tree[y] + 1, tree[x]));
  return ans;
}
int LCA(int x, int y) {
  while (top[x] != top[y]) {
    if (d[top[x]] > d[top[y]])
      x = fa[top[x]];
    else
      y = fa[top[y]];
  }
  return d[x] < d[y] ? x : y;
}
int find(int x) {
  if (x != fat[x]) return fat[x] = find(fat[x]);
  return fat[x];
}
void unionn(int x, int y) {
  int fx = find(x);
  int fy = find(y);
  if (fx != fy) {
    fat[fx] = fy;
  }
}
void kruskal() {
  sort(edge + 1, edge + 1 + etot, cmp);
  for (int i = 1; i <= etot; i++) {
    int k = 0;
    int x = edge[i].fro;
    int y = edge[i].to;
    if (find(x) != find(y)) {
      unionn(x, y);
      add(x, y, edge[i].val);
      add(y, x, edge[i].val);
      used[edge[i].id] = 1;
    }
    if (k == n - 1) break;
  }
}
int ans[N];
int main() {
  n = read();
  m = read();
  for (int i = 1; i <= m; i++) {
    int u = read();
    int v = read();
    int val = read();
    addd(u, v, val, i);
  }
  for (int i = 1; i <= n; i++) fat[i] = i;
  kruskal();
  dfs1(1);
  dfs2(1, 1);
  build(1, 1, n);
  sort(edge + 1, edge + etot + 1, mmp);
  memset(minn, 0x77, sizeof(minn));
  memset(lazy, 0x77, sizeof(lazy));
  for (int i = 1; i <= m; i++) {
    if (!used[edge[i].id]) {
      int x = edge[i].fro;
      int y = edge[i].to;
      int lca = LCA(x, y);
      getqumin(x, lca, edge[i].val);
      getqumin(y, lca, edge[i].val);
      ans[edge[i].id] = max(getmax(x, lca), getmax(y, lca)) - 1;
    }
  }
  for (int i = 1; i <= m; i++) {
    if (used[edge[i].id]) {
      int v;
      if (d[edge[i].to] > d[edge[i].fro])
        v = querymin(1, 1, n, tree[edge[i].to]);
      else
        v = querymin(1, 1, n, tree[edge[i].fro]);
      if (v == inf)
        ans[edge[i].id] = -1;
      else
        ans[edge[i].id] = v - 1;
    }
  }
  for (int i = 1; i <= m; i++) printf("%d ", ans[i]);
}
