#include <bits/stdc++.h>   using namespace std;   namespace Dango {   const int MAXN = 200005, INF = 0x3f3f3f3f;   struct Edge {     int from, to, dis, id;     bool operator<(const Edge b) const { return dis < b.dis; }   } e[MAXN];   struct tree {     int l, r, data;     bool tag;   } t[MAXN << 2];   int n, m;   int head[MAXN], to[MAXN * 2], dis[MAXN * 2], nxt[MAXN * 2];   int fa[MAXN];   int ans[MAXN];   int size[MAXN], maxson[MAXN], belong[MAXN], f[MAXN];   int id[MAXN], link[MAXN], tmp[MAXN], d[MAXN];   bool flag[MAXN];   int read() {     int x = 0, f = 0;     char ch = getchar();     while (!isdigit(ch)) {       f |= (ch ==  - );       ch = getchar();     }     while (isdigit(ch)) {       x = x * 10 + ch -  0 ;       ch = getchar();     }     return f ? -x : x;   }   int ffind(int a) { return f[a] == a ? a : f[a] = ffind(f[a]); }   void add(int u, int v, int w) {     static int cnt;     cnt++;     to[cnt] = v;     dis[cnt] = w;     nxt[cnt] = head[u];     head[u] = cnt;   }   void dfs1(int u, int f) {     size[u] = 1;     fa[u] = f;     d[u] = d[f] + 1;     for (int i = head[u]; i; i = nxt[i]) {       int v = to[i];       if (v == f) continue;       tmp[v] = dis[i];       dfs1(v, u);       size[u] += size[v];       if (size[v] > size[maxson[u]]) maxson[u] = v;     }   }   void dfs2(int u, int f, int anc) {     static int cnt;     id[u] = ++cnt;     link[cnt] = u;     belong[u] = anc;     if (maxson[u]) dfs2(maxson[u], u, anc);     for (int i = head[u]; i; i = nxt[i]) {       int v = to[i];       if (v == f || v == maxson[u]) continue;       dfs2(v, u, v);     }   }   void build(int a, int l, int r) {     t[a].l = l;     t[a].r = r;     t[a].tag = false;     if (l == r) {       t[a].data = tmp[link[l]];       return;     }     int mid = (l + r) >> 1;     build(a << 1, l, mid);     build(a << 1 | 1, mid + 1, r);     t[a].data = max(t[a << 1].data, t[a << 1 | 1].data);   }   void pushdown(int a) {     int l = a << 1, r = a << 1 | 1;     t[a].tag = false;     t[l].data = min(t[l].data, t[a].data);     t[r].data = min(t[r].data, t[a].data);     t[l].tag = t[r].tag = true;   }   void update(int a, int l, int r, int data) {     if (t[a].l >= l && t[a].r <= r) {       t[a].data = min(t[a].data, data);       t[a].tag = true;       return;     }     if (t[a].tag) pushdown(a);     int mid = (t[a].l + t[a].r) >> 1;     if (l <= mid) update(a << 1, l, r, data);     if (r > mid) update(a << 1 | 1, l, r, data);   }   int querymax(int a, int l, int r) {     if (t[a].l >= l && t[a].r <= r) return t[a].data;     if (t[a].tag) pushdown(a);     int mid = (t[a].l + t[a].r) >> 1, res = 0;     if (l <= mid) res = max(res, querymax(a << 1, l, r));     if (r > mid) res = max(res, querymax(a << 1 | 1, l, r));     return res;   }   int querymin(int a, int l, int r) {     if (t[a].l >= l && t[a].r <= r) return t[a].data;     if (t[a].tag) pushdown(a);     int mid = (t[a].l + t[a].r) >> 1, res = INF;     if (l <= mid) res = min(res, querymin(a << 1, l, r));     if (r > mid) res = min(res, querymin(a << 1 | 1, l, r));     return res;   }   int solve(int u, int v) {     int res = 0;     while (belong[u] != belong[v]) {       if (d[belong[u]] < d[belong[v]]) swap(u, v);       res = max(res, querymax(1, id[belong[u]], id[u]));       u = fa[belong[u]];     }     if (u != v) {       if (d[u] > d[v]) swap(u, v);       res = max(res, querymax(1, id[u] + 1, id[v]));     }     return res - 1;   }   void fix(int u, int v, int w) {     while (belong[u] != belong[v]) {       if (d[belong[u]] < d[belong[v]]) swap(u, v);       update(1, id[belong[u]], id[u], w);       u = fa[belong[u]];     }     if (u != v) {       if (d[u] > d[v]) swap(u, v);       update(1, id[u] + 1, id[v], w);     }   }   int solve2(int u, int v) {     int res = INF;     while (belong[u] != belong[v]) {       if (d[belong[u]] < d[belong[v]]) swap(u, v);       res = min(res, querymin(1, id[belong[u]], id[u]));       u = fa[belong[u]];     }     if (u != v) {       if (d[u] > d[v]) swap(u, v);       res = min(res, querymin(1, id[u] + 1, id[v]));     }     if (res == INF) res = 0;     return res - 1;   }   int work() {     n = read();     m = read();     for (int i = 1; i <= n; i++) f[i] = i;     for (int i = 1; i <= m; i++) {       e[i].from = read();       e[i].to = read();       e[i].dis = read();       e[i].id = i;     }     sort(e + 1, e + m + 1);     for (int i = 1; i <= m; i++) {       int u = e[i].from, v = e[i].to, w = e[i].dis;       int a = ffind(u), b = ffind(v);       if (a != b) {         f[a] = b;         add(u, v, w);         add(v, u, w);       } else         flag[i] = true;     }     dfs1(1, 0);     dfs2(1, 0, 1);     build(1, 1, n);     for (int i = 1; i <= m; i++) {       if (!flag[i]) continue;       ans[e[i].id] = solve(e[i].from, e[i].to);     }     memset(tmp, INF, sizeof(tmp));     build(1, 1, n);     for (int i = 1; i <= m; i++) {       if (!flag[i]) continue;       fix(e[i].from, e[i].to, e[i].dis);     }     for (int i = 1; i <= m; i++) {       if (flag[i]) continue;       ans[e[i].id] = solve2(e[i].from, e[i].to);     }     for (int i = 1; i <= m; i++) printf( %d  , ans[i]);     return 0;   }   }  // namespace Dango   int main() { return Dango::work(); }