#include <bits/stdc++.h>
using namespace std;
void use_cio() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
}
template <class L, class R>
ostream &operator<<(ostream &os, pair<L, R> P) {
  return os << "(" << P.first << "," << P.second << ")";
}
template <class T>
ostream &operator<<(ostream &os, vector<T> V) {
  os << "[";
  for (auto x : V) os << x << ", ";
  return os << "]";
}
template <typename... Args>
void dbg(Args... args) {
  ((cerr << args << " "), ...);
  cerr << "\n";
}
const int MAXN = 1e5 + 10;
int sz[MAXN], dep[MAXN], par[MAXN][20], c[MAXN], is_leaf[MAXN], mn[MAXN];
int comp[MAXN], head[MAXN], lab[MAXN], pv1, pv2;
vector<pair<int, int>> adj[MAXN];
struct SegTreeMax {
  int n;
  vector<int> t;
  SegTreeMax(int size) : n(size), t(2 * n + 5, 0) {}
  int merge(int a, int b) { return max(a, b); }
  void build() {
    for (int i = n - 1; i > 0; --i) t[i] = merge(t[i << 1], t[i << 1 | 1]);
  }
  void upd(int p, int val) {
    for (t[p += n] = val; p > 1; p >>= 1) t[p >> 1] = merge(t[p], t[p ^ 1]);
  }
  int qry(int l, int r) {
    int ret = 0;
    for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
      if (l & 1) ret = merge(ret, t[l++]);
      if (r & 1) ret = merge(ret, t[--r]);
    }
    return ret;
  }
} seg(MAXN);
struct SegTreeMin {
  int n;
  vector<int> t;
  SegTreeMin(int size) : n(size), t(2 * n + 5, 1e9) {}
  int merge(int a, int b) { return min(a, b); }
  void build() {
    for (int i = n - 1; i > 0; --i) t[i] = merge(t[i << 1], t[i << 1 | 1]);
  }
  void upd(int l, int r, int val) {
    for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
      if (l & 1) t[l] = merge(t[l], val), l++;
      if (r & 1) r--, t[r] = merge(t[r], val);
    }
  }
  int qry(int p) {
    int ret = 1e9;
    for (p += n; p > 0; p >>= 1) ret = merge(ret, t[p]);
    return ret;
  }
} seg2(MAXN);
struct UnionFind {
  vector<int> par;
  UnionFind(int n) : par(n) { iota(par.begin(), par.end(), 0); }
  void join(int x, int y) { par[root(x)] = root(y); }
  int root(int x) { return par[x] != x ? (par[x] = root(par[x])) : x; }
};
void dfs(int cur, int p) {
  sz[cur] = 1;
  for (auto [nxt, cost] : adj[cur]) {
    if (nxt == p) continue;
    dep[nxt] = dep[cur] + 1;
    par[nxt][0] = cur;
    c[nxt] = cost;
    dfs(nxt, cur);
    sz[cur] += sz[nxt];
  }
  if (sz[cur] == 1) is_leaf[cur] = 1;
}
void hld(int cur, int p) {
  sort(adj[cur].begin(), adj[cur].end(),
       [&](pair<int, int> a, pair<int, int> b) {
         return sz[a.first] > sz[b.first];
       });
  int ok = 0;
  for (auto [nxt, cost] : adj[cur]) {
    if (nxt == p) continue;
    if (ok) {
      comp[nxt] = ++pv1;
      head[pv1] = nxt;
    } else
      ok = 1, comp[nxt] = comp[cur];
    lab[nxt] = ++pv2;
    hld(nxt, cur);
  }
}
int lca(int u, int v) {
  if (dep[u] > dep[v]) swap(u, v);
  for (int i = 0, d = dep[v] - dep[u]; i < 20; i++)
    if (d & (1 << i)) v = par[v][i];
  for (int i = 20; i--;)
    if (par[u][i] != par[v][i]) u = par[u][i], v = par[v][i];
  return (u == v ? u : par[u][0]);
}
int qry(int u, int v) {
  int ret = 0;
  while (comp[u] != comp[v]) {
    ret = max(ret, seg.qry(lab[head[comp[u]]], lab[u] + 1));
    u = par[head[comp[u]]][0];
  }
  ret = max(ret, seg.qry(lab[v] + 1, lab[u] + 1));
  return ret;
}
void upd(int u, int v, int c) {
  while (comp[u] != comp[v]) {
    seg2.upd(lab[head[comp[u]]], lab[u] + 1, c);
    u = par[head[comp[u]]][0];
  }
  seg2.upd(lab[v] + 1, lab[u] + 1, c);
}
vector<tuple<int, int, int, int>> edgs;
vector<int> inuse;
int main() {
  use_cio();
  int n, m;
  cin >> n >> m;
  edgs.resize(m);
  inuse.resize(m);
  UnionFind uf1(n + 1);
  for (int i = 0; i < (m); i++) {
    cin >> get<1>(edgs[i]) >> get<2>(edgs[i]) >> get<0>(edgs[i]);
    get<3>(edgs[i]) = i;
  }
  sort(edgs.begin(), edgs.end());
  for (auto [c, u, v, i] : edgs) {
    if (uf1.root(u) == uf1.root(v)) continue;
    uf1.join(u, v);
    inuse[i] = 1;
    adj[u].emplace_back(v, c);
    adj[v].emplace_back(u, c);
  }
  dfs(1, -1);
  head[1] = comp[1] = lab[1] = pv1 = pv2 = 1;
  hld(1, -1);
  for (int j = 0; j < (19); j++)
    for (int i = (2); i < (n + 1); i++) par[i][j + 1] = par[par[i][j]][j];
  for (int i = (2); i < (n + 1); i++) seg.upd(lab[i], c[i]);
  for (auto [c, u, v, i] : edgs) {
    if (!inuse[i]) {
      int l = lca(u, v);
      upd(u, l, c);
      upd(v, l, c);
    }
  }
  vector<int> ans(m, 0);
  for (auto [c, u, v, i] : edgs) {
    if (inuse[i]) {
      int l = lca(u, v);
      int chd = (l == u) ? v : u;
      ans[i] = seg2.qry(lab[chd]);
    } else {
      int l = lca(u, v);
      ans[i] = max(qry(u, l), qry(v, l));
    }
  }
  for (int i = 0; i < (m); i++) cout << ans[i] << "\n";
}
