#include <bits/stdc++.h>
using namespace std;
template <class T, class T1>
void chkmax(T &x, const T1 &y) {
  if (x < y) x = y;
}
template <class T, class T1>
void chkmin(T &x, const T1 &y) {
  if (x > y) x = y;
}
const int MAXN = (1 << 20);
const int inf = (int)1e9 + 42;
struct node {
  int mn, lazy;
  node() {
    mn = inf;
    lazy = inf;
  }
  node(int val) {
    mn = val;
    lazy = inf;
  }
};
node temp, broken;
node merge(node l, node r) {
  temp.mn = min(l.mn, r.mn);
  temp.lazy = inf;
  return temp;
}
struct segment_tree {
  node tr[4 * MAXN];
  void push(int l, int r, int idx) {
    if (tr[idx].lazy != inf) {
      chkmin(tr[idx].mn, tr[idx].lazy);
      if (l != r) {
        chkmin(tr[2 * idx + 1].lazy, tr[idx].lazy);
        chkmin(tr[2 * idx + 2].lazy, tr[idx].lazy);
      }
      tr[idx].lazy = inf;
    }
  }
  void init(int l, int r, int idx) {
    if (l == r) {
      tr[idx] = node(inf);
      return;
    }
    int mid = (l + r) >> 1;
    init(l, mid, 2 * idx + 1);
    init(mid + 1, r, 2 * idx + 2);
    tr[idx] = merge(tr[2 * idx + 1], tr[2 * idx + 2]);
  }
  void update(int qL, int qR, int val, int l, int r, int idx) {
    push(l, r, idx);
    if (qL > r || l > qR) return;
    if (qL <= l && r <= qR) {
      tr[idx].lazy = val;
      push(l, r, idx);
      return;
    }
    int mid = (l + r) >> 1;
    update(qL, qR, val, l, mid, 2 * idx + 1);
    update(qL, qR, val, mid + 1, r, 2 * idx + 2);
    tr[idx] = merge(tr[2 * idx + 1], tr[2 * idx + 2]);
  }
  node query(int qL, int qR, int l, int r, int idx) {
    push(l, r, idx);
    if (l > qR || r < qL) return broken;
    if (qL <= l && r <= qR) return tr[idx];
    int mid = (l + r) >> 1;
    return merge(query(qL, qR, l, mid, 2 * idx + 1),
                 query(qL, qR, mid + 1, r, 2 * idx + 2));
  }
};
struct dsu {
  vector<int> par, sz;
  dsu() { par.clear(), sz.clear(); }
  void init(int n) {
    par.resize(n + 1);
    sz.resize(n + 1);
    for (int i = 0; i <= n; i++) par[i] = i, sz[i] = 1;
  }
  int root(int x) { return x == par[x] ? x : (par[x] = root(par[x])); }
  bool connected(int u, int v) { return root(u) == root(v); }
  void unite(int u, int v) {
    u = root(u), v = root(v);
    if (u == v) return;
    if (sz[u] < sz[v]) swap(u, v);
    par[v] = u, sz[u] += sz[v];
  }
};
int n, m;
pair<int, pair<int, int> > e[MAXN], initial_e[MAXN];
void read() {
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    cin >> e[i].second.first >> e[i].second.second >> e[i].first;
    initial_e[i] = e[i];
  }
}
dsu d;
vector<pair<int, int> > adj[MAXN];
int tr_sz[MAXN];
void pre_dfs(int u, int pr) {
  tr_sz[u] = 1;
  for (pair<int, int> q : adj[u]) {
    int v = q.first, w = q.second;
    if (v == pr) continue;
    pre_dfs(v, u);
    tr_sz[u] += tr_sz[v];
  }
}
int head[MAXN];
int dfs_time = 0, st[MAXN], en[MAXN];
int par[MAXN][20];
void decompose(int u, int pr, int head) {
  ::head[u] = head;
  st[u] = ++dfs_time;
  par[u][0] = pr;
  for (int l = 1; l < 20; l++) par[u][l] = par[par[u][l - 1]][l - 1];
  pair<int, int> B = {-1, -1};
  for (pair<int, int> q : adj[u]) {
    int v = q.first;
    if (v == pr) continue;
    chkmax(B, make_pair(tr_sz[v], v));
  }
  if (B.second != -1) decompose(B.second, u, head);
  for (pair<int, int> q : adj[u]) {
    int v = q.first;
    if (v == pr || v == B.second) continue;
    decompose(v, u, v);
  }
  en[u] = dfs_time;
}
inline bool upper(int x, int y) { return st[x] <= st[y] && en[y] <= en[x]; }
int lca(int u, int v) {
  if (upper(u, v)) return u;
  if (upper(v, u)) return v;
  for (int l = 19; l >= 0; l--)
    if (!upper(par[u][l], v)) u = par[u][l];
  return par[u][0];
}
vector<pair<int, int> > get_path_up(int u, int anc) {
  vector<pair<int, int> > ret;
  while (st[anc] < st[u]) {
    ret.push_back({max(st[anc] + 1, st[head[u]]), st[u]});
    u = par[head[u]][0];
  }
  return ret;
}
vector<pair<int, int> > get_path(int u, int v) {
  int l = lca(u, v);
  vector<pair<int, int> > f = get_path_up(u, l);
  vector<pair<int, int> > s = get_path_up(v, l);
  while (!s.empty()) f.push_back(s.back()), s.pop_back();
  return f;
}
bool is_edge_in_mst(int u, int v) {
  if (par[u][0] == v) return true;
  if (par[v][0] == u) return true;
  return false;
}
vector<int> add[MAXN], rem[MAXN];
segment_tree t1, t2;
void solve() {
  d.init(n);
  sort(e, e + m);
  for (int i = 0; i < m; i++) {
    int u = e[i].second.first, v = e[i].second.second, w = e[i].first;
    if (!d.connected(u, v)) {
      d.unite(u, v);
      adj[u].push_back({v, w});
      adj[v].push_back({u, w});
    }
  }
  pre_dfs(1, 1);
  decompose(1, 1, 1);
  t1.init(1, dfs_time, 0);
  t2.init(1, dfs_time, 0);
  for (int i = 0; i < m; i++) {
    int u = e[i].second.first, v = e[i].second.second, w = e[i].first;
    if (is_edge_in_mst(u, v)) {
      if (par[u][0] != v) swap(u, v);
      t2.update(st[u], st[u], -w, 1, dfs_time, 0);
    } else {
      vector<pair<int, int> > E = get_path(u, v);
      for (pair<int, int> it : E)
        t1.update(it.first, it.second, w, 1, dfs_time, 0);
    }
  }
  for (int i = 0; i < m; i++) {
    int u = initial_e[i].second.first, v = initial_e[i].second.second;
    if (is_edge_in_mst(u, v)) {
      if (par[u][0] != v) swap(u, v);
      int ans = t1.query(st[u], st[u], 1, dfs_time, 0).mn;
      if (ans == inf)
        ans = -1;
      else
        ans = ans - 1;
      cout << ans << " ";
    } else {
      int ans = inf;
      vector<pair<int, int> > E = get_path(u, v);
      for (pair<int, int> it : E)
        chkmin(ans, t2.query(it.first, it.second, 1, dfs_time, 0).mn);
      if (ans == inf)
        ans = -1;
      else
        ans = -ans - 1;
      cout << ans << " ";
    }
  }
  cout << '\n';
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  read();
  solve();
  return 0;
}
