#include <bits/stdc++.h>
using namespace std;
#define N (101*1000)
#define ll int
#define INF ((ll)1e9)
#define MOD ((ll)1e9+7)

ll n,m,par[N],mark[N];
long long ans;
vector <ll> e[N];
vector <pair<ll,ll> > ed;
map <pair<ll,ll>,bool> mp;

ll root(ll x){if(par[x]<0)return x;return par[x]=root(par[x]);}
void merge(ll x,ll y){if(par[x]==par[y])return ;par[root(y)]=root(x);}

void dfs(ll x)
{
    for(int i=0;i<e[x].size();i++)
    {
        if(mark[e[x][i]]==mark[x]){cout<<0;exit(0);}
        if(!mark[e[x][i]])mark[e[x][i]]=((mark[x]==1)?2:1),dfs(e[x][i]);
    }
}

int main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++)par[i]=-i;
    for(int i=0;i<m;i++)
    {
        ll v,u,p;
        cin>>v>>u>>p;
        if(p)merge(v,u);
        else ed.push_back({v,u});
    }
    for(int i=0;i<ed.size();i++)
    {
        if(root(ed[i].first)==root(ed[i].second))return cout<<0,0;
        ll v=-par[root(ed[i].first)],u=-par[root(ed[i].second)];
        if(mp[{v,u}]==0 && mp[{u,v}]==0)
            e[v].push_back(u),e[u].push_back(v),mp[{v,u}]=1;

    }
    for(int i=1;i<=n;i++)
        if(!mark[i] && i==-par[root(i)])
        {
            if(!ans)ans=1;
            else ans*=2;ans%=MOD;
            mark[i]=1;
            dfs(i);
        }
    cout<<ans;
    return 0;
}


#include <bits/stdc++.h>
#define N 256101
#define M 426835
#define LN 18
#define INF 0x3e3e3e3e
using namespace std;

struct edge{
	int u, v, w, id; bool mst;
	edge (int u0 = 0, int v0 = 0, int w0 = 0, int id0 = 0): u(u0), v(v0), w(w0), id(id0), mst(false) {}
	edge * read(int id0) {scanf("%d%d%d", &u, &v, &w); id = id0; return this;}
	bool operator < (const edge &B) const {return w < B.w;}
}e[M];

int V, E;
int first[N], next[M];
int p[N], dep[N], ans[N];
int P[LN + 1][N], *pa = *P;
int W[LN + 1][N], *we = *W;
int C[LN + 1][N], *cx = *C;

inline void up(int &x, const int y) {x < y ? x = y : 0;}
inline void down(int &x, const int y) {x > y ? x = y : 0;}
inline int ancestor(int x) {return p[x] == x ? x : (p[x] = ancestor(p[x]));}
inline bool test(int x, int y, bool un = false){
	if((x = ancestor(x)) == (y = ancestor(y))) return true;
	if(un) p[x] = y; return false;
}
inline void addedge(int id){
	next[id] = first[e[id].u]; first[e[id].u] = id; e[id].mst = true; id += E;
	next[id] = first[e[id].u]; first[e[id].u] = id; e[id].mst = true;
}

void Kruskal(){
	int i, Es = 0;
	for(i = 1; i <= V; ++i) p[i] = i;
	sort(e + 1, e + (E + 1));
	for(i = 1; i <= E; ++i) e[E + i] = edge(e[i].v, e[i].u, e[i].w, e[i].id);
	for(i = 1; i <= E; ++i)
		if(!test(e[i].u, e[i].v, true)){
			addedge(i);
			if(++Es >= V - 1) return;
		}
}

void dfs(int x){
	int i, y;
	for(i = 0; i < LN && P[i][x]; ++i){
		P[i + 1][x] = P[i][P[i][x]];
		W[i + 1][x] = max(W[i][x], W[i][P[i][x]]);
	}
	for(i = first[x]; i; i = next[i])
		if(e[i].mst && (y = e[i].v) != pa[x]){
			pa[y] = x; we[y] = e[i].w;
			dep[y] = dep[x] + 1; dfs(y);
		}
}

int query(int x, int y){
	int i, w = 0;
	if(dep[x] < dep[y]) swap(x, y);
	for(i = LN; i >= 0; --i)
		if(dep[x] - (1 << i) >= dep[y]){
			up(w, W[i][x]); x = P[i][x];
		}
	if(x == y) return w;
	for(i = LN; i >= 0; --i)
		if(P[i][x] != P[i][y]){
			up(w, W[i][x]); x = P[i][x];
			up(w, W[i][y]); y = P[i][y];
		}
	up(w, we[x]); up(w, we[y]);
	return w;
}

void adj(int x, int y, int v){
	int i;
	if(dep[x] < dep[y]) swap(x, y);
	for(i = LN; i >= 0; --i)
		if(dep[x] - (1 << i) >= dep[y]){
			down(C[i][x], v); x = P[i][x];
		}
	if(x == y) return;
	for(i = LN; i >= 0; --i)
		if(P[i][x] != P[i][y]){
			down(C[i][x], v); x = P[i][x];
			down(C[i][y], v); y = P[i][y];
		}
	down(cx[x], v); down(cx[y], v);
}

int main(){
	int i, j;
	scanf("%d%d", &V, &E);
	for(i = 1; i <= E; ++i) e[i].read(i);
	Kruskal();
	dep[1] = 1; dfs(1);
	memset(C, 63, sizeof C);
	for(i = 1; i <= E; ++i)
		if(!e[i].mst){
			ans[e[i].id] = query(e[i].u, e[i].v) - 1;
			adj(e[i].u, e[i].v, e[i].w);
		}
	for(i = LN - 1; i >= 0; --i)
		for(j = 1; j <= V; ++j){
			down(C[i][j], C[i + 1][j]); down(C[i][P[i][j]], C[i + 1][j]);
		}
	for(i = 1; i <= E; ++i)
		if(e[i].mst){
			j = (dep[e[i].u] < dep[e[i].v] ? e[i].v : e[i].u);
			ans[e[i].id] = cx[j] - 1;
		}
	for(i = 1; i <= E; ++i)
		printf("%d%c", ans[i] >= INF ? -1 : ans[i], i == E ? 10 : 32);
	return 0;
}


#include <bits/stdc++.h>
#define N 256101
#define M 426835
#define LN 18
#define INF 0x3e3e3e3e
using namespace std;

struct edge{
	int u, v, w, id; bool mst;
	edge (int u0 = 0, int v0 = 0, int w0 = 0, int id0 = 0): u(u0), v(v0), w(w0), id(id0), mst(false) {}
	edge * read(int id0) {scanf("%d%d%d", &u, &v, &w); id = id0; return this;}
	bool operator < (const edge &B) const {return w < B.w;}
}e[M];

int V, E;
int first[N], next[M];
int p[N], dep[N], ans[N];
int P[LN + 1][N], *pa = *P;
int W[LN + 1][N], *we = *W;
int C[LN + 1][N], *cx = *C;

inline void up(int &x, const int y) {x < y ? x = y : 0;}
inline void down(int &x, const int y) {x > y ? x = y : 0;}
inline int ancestor(int x) {return p[x] == x ? x : (p[x] = ancestor(p[x]));}
inline bool test(int x, int y, bool un = false){
	if((x = ancestor(x)) == (y = ancestor(y))) return true;
	if(un) p[x] = y; return false;
}
inline void addedge(int id){
	printf("addedge %d %d %d\n", e[id].u, e[id].v, e[id].w);
	next[id] = first[e[id].u]; first[e[id].u] = id; e[id].mst = true; id += E;
	next[id] = first[e[id].u]; first[e[id].u] = id; e[id].mst = true;
}

void Kruskal(){
	int i, Es = 0;
	for(i = 1; i <= V; ++i) p[i] = i;
	sort(e + 1, e + (E + 1));
	for(i = 1; i <= E; ++i) e[E + i] = edge(e[i].v, e[i].u, e[i].w, e[i].id);
	for(i = 1; i <= E; ++i)
		if(!test(e[i].u, e[i].v, true)){
			addedge(i);
			if(++Es >= V - 1) return;
		}
}

void dfs(int x){
	int i, y;
	for(i = 0; i < LN && P[i][x]; ++i){
		P[i + 1][x] = P[i][P[i][x]];
		W[i + 1][x] = max(W[i][x], W[i][P[i][x]]);
	}
	for(i = first[x]; i; i = next[i])
		if(e[i].mst && (y = e[i].v) != pa[x]){
			pa[y] = x; we[y] = e[i].w;
			dep[y] = dep[x] + 1; dfs(y);
		}
}

int query(int x, int y){
	int i, w = 0;
	if(dep[x] < dep[y]) swap(x, y);
	for(i = LN; i >= 0; --i)
		if(dep[x] - (1 << i) >= dep[y]){
			up(w, W[i][x]); x = P[i][x];
		}
	if(x == y) return w;
	for(i = LN; i >= 0; --i)
		if(P[i][x] != P[i][y]){
			up(w, W[i][x]); x = P[i][x];
			up(w, W[i][y]); y = P[i][y];
		}
	up(w, we[x]); up(w, we[y]);
	return w;
}

void adj(int x, int y, int v){
	int i;
	if(dep[x] < dep[y]) swap(x, y);
	for(i = LN; i >= 0; --i)
		if(dep[x] - (1 << i) >= dep[y]){
			down(C[i][x], v); x = P[i][x];
		}
	if(x == y) return;
	for(i = LN; i >= 0; --i)
		if(P[i][x] != P[i][y]){
			down(C[i][x], v); x = P[i][x];
			down(C[i][y], v); y = P[i][y];
		}
	down(cx[x], v); down(cx[y], v);
}

int main(){
	int i, j;
	scanf("%d%d", &V, &E);
	for(i = 1; i <= E; ++i) e[i].read(i);
	Kruskal();
	dep[1] = 1; dfs(1);
	memset(C, 63, sizeof C);
	for(i = 1; i <= E; ++i)
		if(!e[i].mst){
			ans[e[i].id] = query(e[i].u, e[i].v) - 1;
			adj(e[i].u, e[i].v, e[i].w);
		}
	for(i = LN - 1; i >= 0; --i)
		for(j = 1; j <= V; ++j){
			down(C[i][j], C[i + 1][j]); down(C[i][P[i][j]], C[i + 1][j]);
		}
	for(i = 1; i <= E; ++i)
		if(e[i].mst){
			j = (dep[e[i].u] < dep[e[i].v] ? e[i].v : e[i].u);
			ans[e[i].id] = cx[j] - 1;
		}
	for(i = 1; i <= E; ++i)
		printf("%d%c", ans[i] >= INF ? -1 : ans[i], i == E ? 10 : 32);
	return 0;
}


#include <bits/stdc++.h>
#define N 256101
#define M 426835
#define LN 18
#define INF 0x3e3e3e3e
using namespace std;

struct edge{
	int u, v, w, id; bool mst;
	edge (int u0 = 0, int v0 = 0, int w0 = 0, int id0 = 0): u(u0), v(v0), w(w0), id(id0), mst(false) {}
	edge * read(int id0) {scanf("%d%d%d", &u, &v, &w); id = id0; return this;}
	bool operator < (const edge &B) const {return w < B.w;}
}e[M];

int V, E;
int first[N], next[M];
int p[N], dep[N], ans[N];
int P[LN + 1][N], *pa = *P;
int W[LN + 1][N], *we = *W;
int C[LN + 1][N], *cx = *C;

inline void up(int &x, const int y) {x < y ? x = y : 0;}
inline void down(int &x, const int y) {x > y ? x = y : 0;}
inline int ancestor(int x) {return p[x] == x ? x : (p[x] = ancestor(p[x]));}
inline bool test(int x, int y, bool un = false){
	if((x = ancestor(x)) == (y = ancestor(y))) return true;
	if(un) p[x] = y; return false;
}
inline void addedge(int id){
	next[id] = first[e[id].u]; first[e[id].u] = id; e[id].mst = true; id += E;
	next[id] = first[e[id].u]; first[e[id].u] = id; e[id].mst = true;
}

void Kruskal(){
	int i, Es = 0;
	for(i = 1; i <= V; ++i) p[i] = i;
	sort(e + 1, e + (E + 1));
	for(i = 1; i <= E; ++i) e[E + i] = edge(e[i].v, e[i].u, e[i].w, e[i].id);
	for(i = 1; i <= E; ++i)
		if(!test(e[i].u, e[i].v, true)){
			addedge(i);
			if(++Es >= V - 1) return;
		}
}

void dfs(int x){
	int i, y;
	for(i = 0; i < LN && P[i][x]; ++i){
		P[i + 1][x] = P[i][P[i][x]];
		W[i + 1][x] = max(W[i][x], W[i][P[i][x]]);
	}
	for(i = first[x]; i; i = next[i])
		if(e[i].mst && (y = e[i].v) != pa[x]){
			pa[y] = x; we[y] = e[i].w;
			dep[y] = dep[x] + 1; dfs(y);
		}
}

int query(int x, int y){
	int i, w = 0;
	if(dep[x] < dep[y]) swap(x, y);
	for(i = LN; i >= 0; --i)
		if(dep[x] - (1 << i) >= dep[y]){
			up(w, W[x][i]); x = P[x][i];
		}
	if(x == y) return w;
	for(i = LN; i >= 0; --i)
		if(P[x][i] != P[y][i]){
			up(w, W[x][i]); x = P[x][i];
			up(w, W[y][i]); y = P[y][i];
		}
	up(w, we[x]); up(w, we[y]);
	return w;
}

void adj(int x, int y, int v){
	int i;
	if(dep[x] < dep[y]) swap(x, y);
	for(i = LN; i >= 0; --i)
		if(dep[x] - (1 << i) >= dep[y]){
			down(C[x][i], v); x = P[x][i];
		}
	if(x == y) return;
	for(i = LN; i >= 0; --i)
		if(P[x][i] != P[y][i]){
			down(C[x][i], v); x = P[x][i];
			down(C[y][i], v); y = P[y][i];
		}
	down(cx[x], v); down(cx[y], v);
}

int main(){
	int i, j;
	scanf("%d%d", &V, &E);
	for(i = 1; i <= E; ++i) e[i].read(i);
	Kruskal();
	dfs(1);
	memset(C, 63, sizeof C);
	for(i = 1; i <= E; ++i)
		if(!e[i].mst){
			ans[e[i].id] = query(e[i].u, e[i].v) - 1;
			adj(e[i].u, e[i].v, e[i].w);
		}
	for(i = 1; i <= E; ++i)
		if(e[i].mst){
			j = (dep[e[i].u] < dep[e[i].v] ? e[i].v : e[i].u);
			ans[e[i].id] = cx[j] - 1;
		}
	for(i = 1; i <= E; ++i)
		printf("%d%c", ans[i] >= INF ? -1 : ans[i], i == E ? 10 : 32);
	return 0;
}


#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>

using namespace std;

void maximiza(int &a,int b)
{
  a=max(a,b);
}

const int primero=1<<19;
const int tope=1<<20;

int minimo[tope];

void inserta(int pos,int prof)
{
  pos+=primero;
  minimo[pos]=prof;
  while (pos>1) {
    pos/=2;
    minimo[pos]=min(minimo[2*pos],minimo[2*pos+1]);
  }
}

int minimoentre(int pos0,int pos1)
{
  pos0+=primero;
  pos1+=primero;
  if (pos0==pos1) return minimo[pos0];
  if (pos0>pos1) swap(pos0,pos1);
  int mini=min(minimo[pos0],minimo[pos1]);
  while (pos0+1<pos1) {
    if (pos0%2==0) mini=min(mini,minimo[pos0+1]);
    pos0/=2;
    if (pos1%2==1) mini=min(mini,minimo[pos1-1]);
    pos1/=2;
  }
  return mini;
}

const int limite=200005;

int n,m;
int identificador[limite];

int computaidentificador(int u)
{
  int &idu=identificador[u];
  if (idu==0) return u;
  idu=computaidentificador(idu);
  return idu;
}

void fusiona(int u,int v)
{
  u=computaidentificador(u);
  v=computaidentificador(v);
  if (u==v) return;
  identificador[u]=v;
}

int au[limite],av[limite],ac[limite],asol[limite];
int enarbol[limite];

vector<pair<int,int> > g[limite];
int padre[limite][20];
int cpadre[limite][20];
int apadre[limite];
int profundidad[limite];
int posle[limite];
int numpos=1;
int padrevive[limite];
int muerto[limite];

int matar(int u,int prof,int c)
{
  if (profundidad[u]<=prof) return u;
  if (not muerto[u]) {
    muerto[u]=1;
    asol[apadre[u]]=c;
  }
  padrevive[u]=matar(padrevive[u],prof,c);
  return padrevive[u];
}

void generapadre(int u,int p,int ap,int prof)
{
  posle[u]=numpos++;
  profundidad[u]=prof;
  inserta(posle[u],prof);
  padrevive[u]=p;
  padre[u][0]=p;
  apadre[u]=ap;
  cpadre[u][0]=ac[ap];
  for (int i=1;i<20;i++) {
    padre[u][i]=padre[padre[u][i-1]][i-1];
    cpadre[u][i]=max(cpadre[u][i-1],cpadre[padre[u][i-1]][i-1]);
  }
  vector<pair<int,int> > &ar=g[u];
  for (int i=0;i<int(ar.size());i++) {
    int v=ar[i].first;
    int au=ar[i].second;
    if (v!=p) {
      generapadre(v,u,au,prof+1);
      inserta(numpos++,prof);
    }
  }
}

int obtencoste(int u,int salto)
{
  //cout<<"obtencoste u "<<u<<" salto "<<salto;
  int c=0;
  for (int b=0;b<20;b++) {
    if (salto&(1<<b)) {
      c=max(c,cpadre[u][b]);
      u=padre[u][b];
    }
  }
  //cout<<" c "<<c<<endl;
  return c;
}

int costeentre(int u,int v)
{
  int prof=minimoentre(posle[u],posle[v]);
  //cout<<"costeentre u "<<u<<" v "<<v<<" prof "<<prof<<endl;
  int c=max(obtencoste(u,profundidad[u]-prof),obtencoste(v,profundidad[v]-prof));
  return c;
}

bool compara(int i1,int i2)
{
  return ac[i1]<ac[i2];
}

int indice[limite];

int main()
{
  ios::sync_with_stdio(false);
  cin>>n>>m;
  for (int i=0;i<m;i++) {
    int u,v,c;
    cin>>u>>v>>c;
    au[i]=u;
    av[i]=v;
    ac[i]=c;
    indice[i]=i;
  }
  sort(indice,indice+m,compara);
  for (int iindice=0;iindice<m;iindice++) {
    int i=indice[iindice];
    int u=au[i];
    int v=av[i];
    if (computaidentificador(u)!=computaidentificador(v)) {
      fusiona(u,v);
      enarbol[i]=1;
      g[u].push_back(pair<int,int> (v,i));
      g[v].push_back(pair<int,int> (u,i));
    }
  }
  generapadre(1,0,0,1);
  for (int i=0;i<m;i++)
    asol[i]=-1;
  for (int iindice=0;iindice<m;iindice++) {
    int i=indice[iindice];
    int u=au[i];
    int v=av[i];
    int c=ac[i];
    if (not enarbol[i]) {
      asol[i]=costeentre(u,v)-1;
      int prof=minimoentre(posle[u],posle[v]);
      matar(u,prof,c-1);
      matar(v,prof,c-1);
    }
  }
  for (int i=0;i<m;i++) {
    if (i>0) cout<<" ";
    cout<<asol[i];
  }
  cout<<endl;
}


using namespace std;
#include<bits/stdc++.h>
#define debug(x) clog<<#x<<" = "<<x<<'\n'
#define ll long long
#define pll pair<ll,ll>
#define pii pair<int,int>
#define fir first
#define sec second
#define mp make_pair
#define pb push_back
#define sz(c) ((int)c.size())
#define all(c) (c).begin(),(c).end()
#define MASK(i) (1LL<<(i))
#define BIT(x,i) (((x)>>(i))&1)
#define fn "827D"  /// ___FILE_NAME_HERE___
#define rep(c,it) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++)
#define __rep(c,it) for(__typeof((c).rbegin()) it=(c).rbegin();it!=(c).rend();it++)

template <class T,class U>
void maximize(T &x,U y)
{
    if(x < y)x=y;
}
template <class T,class U>
void minimize(T &x,U y)
{
    if(x > y)x=y;
}
template <class T>
T Abs(T x)
{
    return (x < 0 ? -x : x);
}
template <class T>
T safe_sqrt(T x)
{
    return sqrt(max(x,(T)0));
}
template <class T,class U,class V>
T addmod(T x,U k,V MOD)
{
    return ((x+k)%MOD + MOD)%MOD;
}
template <class T,class U,class V>
T submod(T x,U k,V MOD)
{
    return ((x-k)%MOD + MOD)%MOD;
}
template <class T,class U,class V>
T mul(T x,U y,V MOD)
{
    return (ll)x*y%MOD;
}
/*------------------------------------------END_OF_TEMPLATE------------------------------------------*/

namespace task{

const int lg=18;
const int inf=2e9;
const int N=2e5+5;
vector <pii> adj[N];
vector <int> id[N];
bool intree[N];
int dp[N][lg+2],d[N],maxEdges[N][lg+2],w[N];
int head[N],pos[N],chainid[N];
int ans[N],szt[N],endE[N];
int n,m,prt=0,nchain=1;

struct E
{
    int u,v,c,idx;
    E(){}
    E(int _u,int _v,int _c,int _idx):u(_u),v(_v),c(_c),idx(_idx){}
    bool operator < (const E &other) const
    {
        return c < other.c;
    }
};
vector <E> edges;

struct Dsu
{
    vector <int> lab;
    Dsu(){lab.resize(N+5,-1);}
    int findp(int u){return lab[u] < 0 ? u : findp(lab[u]);}
    bool join(int u,int v)
    {
        u=findp(u),v=findp(v);
        if(u==v)return true;
        if(lab[u] > lab[v])swap(u,v);
        lab[u]+=lab[v],lab[v]=u;
        return false;
    }
}dsu;

template <class T> struct segmentTree
{
    vector <T> tree,lazy;
    segmentTree()
    {
        tree.resize(4*N+5,inf);
        lazy.resize(4*N+5,inf);
    }
    void pushdown(int node,int l,int r)
    {
        if(lazy[node]==inf)return ;
        minimize(tree[node],lazy[node]);
        if(l != r)
        {
            minimize(lazy[node<<1],lazy[node]);
            minimize(lazy[node<<1|1],lazy[node]);
        }
        lazy[node]=inf;
    }
    void update(int lm,int rm,T val,int l=1,int r=n,int node=1)
    {
        pushdown(node,l,r);
        if(l > r or r < lm or l > rm)return ;
        if(lm <= l and r <= rm)
        {
            minimize(tree[node],val);
            if(l != r)
            {
                minimize(lazy[node<<1],val);
                minimize(lazy[node<<1|1],val);
            }
            return ;
        }
        int mid=(l + r)>>1;
        update(lm,rm,val,l,mid,node<<1);
        update(lm,rm,val,mid+1,r,node<<1|1);
    }
    T query(int p,int l=1,int r=n,int node=1)
    {
        pushdown(node,l,r);
        if(l > r or r < p or l > p)return (T)inf;
        if(l==r)return tree[node];
        int mid=(l + r)>>1;
        return min(query(p,l,mid,node<<1),query(p,mid+1,r,node<<1|1));
    }
};
segmentTree <int> seg;

void dfs(int u,int par)
{
    dp[u][0]=par,szt[u]=1;
    for(int i=0;i<sz(adj[u]);++i)
    {
        int v=adj[u][i].fir;
        int c=adj[u][i].sec;
        if(v == par)continue;
        d[v]=d[u] + 1;
        maxEdges[v][0]=c;
        endE[id[u][i]]=v;
        dfs(v,u);
        szt[u]+=szt[v];
    }
}

void hld(int u,int par)
{
    if(!head[nchain])head[nchain]=u;
    chainid[u]=nchain;
    pos[u]=++prt;
    int bigChild=-1;
    for(auto &i : adj[u])
    {
        int v=i.fir;
        if(v==par or v==bigChild)continue;
        if(bigChild==-1 or szt[v] > szt[bigChild])bigChild=v;
    }
    if(bigChild!=-1)hld(bigChild,u);
    for(auto &i : adj[u])
    {
        int v=i.fir;
        if(v==par or v==bigChild)continue;
        nchain++;
        hld(v,u);
    }
}

void creat()
{
    for(int j=1;j<=lg;++j)
        for(int i=1;i<=n;++i)
    {
        dp[i][j]=dp[dp[i][j-1]][j-1];
        maxEdges[i][j]=max(maxEdges[i][j-1],maxEdges[dp[i][j-1]][j-1]);
    }
}

pii lca(int u,int v)
{
    if(d[u] < d[v])swap(u,v);
    int res=-inf;
    for(int j=lg;j>=0;--j)if(d[dp[u][j]] >= d[v])maximize(res,maxEdges[u][j]),u=dp[u][j];
    if(u==v)return mp(u,res);
    for(int j=lg;j>=0;--j)if(dp[u][j] - dp[v][j])
    {
        maximize(res,maxEdges[u][j]);
        maximize(res,maxEdges[v][j]);
        u=dp[u][j],v=dp[v][j];
    }
    maximize(res,maxEdges[u][0]);
    maximize(res,maxEdges[v][0]);
    return mp(dp[u][0],res);
}

void up(int u,int par,int c)
{
    int uchain,pc=chainid[par];
    while(true)
    {
        uchain=chainid[u];
        if(uchain==pc)
        {
            seg.update(pos[par],pos[u],c);
            return ;
        }
        int headc=head[uchain];
        seg.update(pos[headc],pos[u],c);
        u=dp[headc][0];
    }
}

void solve()
{
    scanf("%d%d",&n,&m);
    for(int u,v,c,i=1;i<=m;++i)
    {
        scanf("%d%d%d",&u,&v,&c);
        edges.pb(E(u,v,c,i));
        w[i]=c;
    }
    sort(all(edges));
    for(auto &i : edges)
    {
        bool flag=dsu.join(i.u,i.v);
        if(flag)continue;
        intree[i.idx]=true;
        adj[i.u].pb(mp(i.v,i.c));
        adj[i.v].pb(mp(i.u,i.c));
        id[i.u].pb(i.idx);
        id[i.v].pb(i.idx);
    }
    dfs(1,1);
    hld(1,1);
    creat();
    fill(ans+1,ans+1+m,inf);
    for(auto &i : edges)if(!intree[i.idx])
    {
        pii lc=lca(i.u,i.v);
        ans[i.idx]=lc.sec;
        up(i.u,lc.fir,w[i.idx]);
        up(i.v,lc.fir,w[i.idx]);
    }
    for(auto &i : edges)if(intree[i.idx])
        ans[i.idx]=seg.query(pos[endE[i.idx]]);
    for(int i=1;i<=m;++i)printf("%d ",(ans[i]==inf ? -1 : ans[i]-1));
}}

int main(void)
{
    #ifndef ONLINE_JUDGE
    freopen(fn".inp","r",stdin);
    freopen(fn".out","w",stdout);
    #endif // ONLINE_JUDGE
    task::solve();
}


using namespace std;
#include<bits/stdc++.h>
#define debug(x) clog<<#x<<" = "<<x<<'\n'
#define ll long long
#define pll pair<ll,ll>
#define pii pair<int,int>
#define fir first
#define sec second
#define mp make_pair
#define pb push_back
#define sz(c) ((int)c.size())
#define all(c) (c).begin(),(c).end()
#define MASK(i) (1LL<<(i))
#define BIT(x,i) (((x)>>(i))&1)
#define fn "827D"  /// ___FILE_NAME_HERE___
#define rep(c,it) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++)
#define __rep(c,it) for(__typeof((c).rbegin()) it=(c).rbegin();it!=(c).rend();it++)

template <class T,class U>
void maximize(T &x,U y)
{
    if(x < y)x=y;
}
template <class T,class U>
void minimize(T &x,U y)
{
    if(x > y)x=y;
}
template <class T>
T Abs(T x)
{
    return (x < 0 ? -x : x);
}
template <class T>
T safe_sqrt(T x)
{
    return sqrt(max(x,(T)0));
}
template <class T,class U,class V>
T addmod(T x,U k,V MOD)
{
    return ((x+k)%MOD + MOD)%MOD;
}
template <class T,class U,class V>
T submod(T x,U k,V MOD)
{
    return ((x-k)%MOD + MOD)%MOD;
}
template <class T,class U,class V>
T mul(T x,U y,V MOD)
{
    return (ll)x*y%MOD;
}
/*------------------------------------------END_OF_TEMPLATE------------------------------------------*/

namespace task{

const int lg=19;
const int inf=2e9;
const int N=2e5+5;
vector <pii> adj[N];
vector <int> id[N];
bool intree[N];
int dp[N][lg+2],d[N],maxEdges[N][lg+2],w[N];
int head[N],pos[N],chainid[N];
int ans[N],szt[N],endE[N];
int n,m,prt=0,nchain=1;

struct E
{
    int u,v,c,idx;
    E(){}
    E(int _u,int _v,int _c,int _idx):u(_u),v(_v),c(_c),idx(_idx){}
    bool operator < (const E &other) const
    {
        return c < other.c;
    }
};
vector <E> edges;

struct Dsu
{
    vector <int> lab;
    Dsu(){lab.resize(N+5,-1);}
    int findp(int u){return lab[u] < 0 ? u : findp(lab[u]);}
    bool join(int u,int v)
    {
        u=findp(u),v=findp(v);
        if(u==v)return true;
        if(lab[u] > lab[v])swap(u,v);
        lab[u]+=lab[v],lab[v]=u;
        return false;
    }
}dsu;

template <class T> struct segmentTree
{
    vector <T> tree,lazy;
    segmentTree()
    {
        tree.resize(4*N+5,inf);
        lazy.resize(4*N+5,inf);
    }
    void pushdown(int node,int l,int r)
    {
        if(lazy[node]==(T)inf)return ;
        minimize(tree[node],lazy[node]);
        if(l != r)
        {
            minimize(lazy[node<<1],lazy[node]);
            minimize(lazy[node<<1|1],lazy[node]);
        }
        lazy[node]=(T)inf;
    }
    void update(int lm,int rm,T val,int l=1,int r=n,int node=1)
    {
        pushdown(node,l,r);
        if(l > r or r < lm or l > rm)return ;
        if(lm <= l and r <= rm)
        {
            minimize(tree[node],val);
            if(l != r)
            {
                minimize(lazy[node<<1],val);
                minimize(lazy[node<<1|1],val);
            }
            return ;
        }
        int mid=(l + r)>>1;
        update(lm,rm,val,l,mid,node<<1);
        update(lm,rm,val,mid+1,r,node<<1|1);
    }
    T query(int p,int l=1,int r=n,int node=1)
    {
        pushdown(node,l,r);
        if(l > r or r < p or l > p)return (T)inf;
        if(l==r)return tree[node];
        int mid=(l + r)>>1;
        return min(query(p,l,mid,node<<1),query(p,mid+1,r,node<<1|1));
    }
};
segmentTree <int> seg;

void dfs(int u,int par)
{
    dp[u][0]=par,szt[u]=1;
    for(int i=0;i<sz(adj[u]);++i)
    {
        int v=adj[u][i].fir;
        int c=adj[u][i].sec;
        if(v == par)continue;
        d[v]=d[u] + 1;
        maxEdges[v][0]=c;
        endE[id[u][i]]=v;
        dfs(v,u);
        szt[u]+=szt[v];
    }
}

void hld(int u,int par)
{
    if(!head[nchain])head[nchain]=u;
    chainid[u]=nchain;
    pos[u]=++prt;
    int bigChild=-1;
    for(auto &i : adj[u])
    {
        int v=i.fir;
        if(v==par or v==bigChild)continue;
        if(bigChild==-1 or szt[v] > szt[bigChild])bigChild=v;
    }
    if(bigChild!=-1)hld(bigChild,u);
    for(auto &i : adj[u])
    {
        int v=i.fir;
        if(v==par or v==bigChild)continue;
        nchain++;
        hld(v,u);
    }
}

void creat()
{
    for(int j=1;j<=lg;++j)
        for(int i=1;i<=n;++i)
    {
        dp[i][j]=dp[dp[i][j-1]][j-1];
        maxEdges[i][j]=max(maxEdges[i][j-1],maxEdges[dp[i][j-1]][j-1]);
    }
}

pii lca(int u,int v)
{
    if(d[u] < d[v])swap(u,v);
    int res=-inf;
    for(int j=lg;j>=0;--j)if(d[dp[u][j]] >= d[v])maximize(res,maxEdges[u][j]),u=dp[u][j];
    if(u==v)return mp(u,res);
    for(int j=lg;j>=0;--j)if(dp[u][j] - dp[v][j])
    {
        maximize(res,maxEdges[u][j]);
        maximize(res,maxEdges[v][j]);
        u=dp[u][j],v=dp[v][j];
    }
    maximize(res,maxEdges[u][0]);
    maximize(res,maxEdges[v][0]);
    return mp(dp[u][0],res);
}

int gett(int u,int par)
{
    for(int j=lg;j>=0;--j)
        if(d[dp[u][j]] - d[par] >= 1)u=dp[u][j];
    return u;
}

void up(int u,int par,int c)
{
    if(u==par)return;
    par = gett(u,par);
    int uchain,pc=chainid[par];
    if(u==par)
    {
        seg.update(pos[par],pos[u],c);
        return;
    }
    while(true)
    {
        uchain=chainid[u];
        if(uchain==pc)
        {
            seg.update(pos[par],pos[u],c);
            return ;
        }
        int headc=head[uchain];
        seg.update(pos[headc],pos[u],c);
        u=dp[headc][0];
    }
}

void solve()
{
    scanf("%d%d",&n,&m);
    for(int u,v,c,i=1;i<=m;++i)
    {
        scanf("%d%d%d",&u,&v,&c);
        edges.pb(E(u,v,c,i));
        w[i]=c;
    }
    sort(all(edges));
    for(auto &i : edges)
    {
        bool flag=dsu.join(i.u,i.v);
        if(flag)continue;
        intree[i.idx]=true;
        adj[i.u].pb(mp(i.v,i.c));
        adj[i.v].pb(mp(i.u,i.c));
        id[i.u].pb(i.idx);
        id[i.v].pb(i.idx);
    }
    dfs(1,1);
    hld(1,1);
    creat();
    fill(ans+1,ans+1+m,inf);
    for(auto &i : edges)if(!intree[i.idx])
    {
        pii lc=lca(i.u,i.v);
        ans[i.idx]=lc.sec;
        up(i.u,lc.fir,w[i.idx]);
        up(i.v,lc.fir,w[i.idx]);
    }
    for(auto &i : edges)if(intree[i.idx])
        ans[i.idx]=seg.query(pos[endE[i.idx]]);
    for(int i=1;i<=m;++i)printf("%d ",(ans[i]==inf ? -1 : --ans[i]));
}}

int main(void)
{
    #ifndef ONLINE_JUDGE
    freopen(fn".inp","r",stdin);
    freopen(fn".out","w",stdout);
    #endif // ONLINE_JUDGE
    task::solve();
}


using namespace std;
#include<bits/stdc++.h>
#define debug(x) clog<<#x<<" = "<<x<<'\n'
#define ll long long
#define pll pair<ll,ll>
#define pii pair<int,int>
#define fir first
#define sec second
#define mp make_pair
#define pb push_back
#define sz(c) ((int)c.size())
#define all(c) (c).begin(),(c).end()
#define MASK(i) (1LL<<(i))
#define BIT(x,i) (((x)>>(i))&1)
#define fn "827D"  /// ___FILE_NAME_HERE___
#define rep(c,it) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++)
#define __rep(c,it) for(__typeof((c).rbegin()) it=(c).rbegin();it!=(c).rend();it++)

template <class T,class U>
void maximize(T &x,U y)
{
    if(x < y)x=y;
}
template <class T,class U>
void minimize(T &x,U y)
{
    if(x > y)x=y;
}
template <class T>
T Abs(T x)
{
    return (x < 0 ? -x : x);
}
template <class T>
T safe_sqrt(T x)
{
    return sqrt(max(x,(T)0));
}
template <class T,class U,class V>
T addmod(T x,U k,V MOD)
{
    return ((x+k)%MOD + MOD)%MOD;
}
template <class T,class U,class V>
T submod(T x,U k,V MOD)
{
    return ((x-k)%MOD + MOD)%MOD;
}
template <class T,class U,class V>
T mul(T x,U y,V MOD)
{
    return (ll)x*y%MOD;
}
/*------------------------------------------END_OF_TEMPLATE------------------------------------------*/

namespace task{

const int lg=19;
const int inf=2e9;
const int N=2e5+5;
vector <pii> adj[N];
vector <int> id[N];
bool intree[N];
int dp[N][lg+2],d[N],maxEdges[N][lg+2],w[N];
int head[N],pos[N],chainid[N];
int ans[N],szt[N],endE[N];
int n,m,prt=0,nchain=1;

struct E
{
    int u,v,c,idx;
    E(){}
    E(int _u,int _v,int _c,int _idx):u(_u),v(_v),c(_c),idx(_idx){}
    bool operator < (const E &other) const
    {
        return c < other.c;
    }
};
vector <E> edges;

struct Dsu
{
    vector <int> lab;
    Dsu(){lab.resize(N+5,-1);}
    int findp(int u){return lab[u] < 0 ? u : findp(lab[u]);}
    bool join(int u,int v)
    {
        u=findp(u),v=findp(v);
        if(u==v)return true;
        if(lab[u] > lab[v])swap(u,v);
        lab[u]+=lab[v],lab[v]=u;
        return false;
    }
}dsu;

template <class T> struct segmentTree
{
    vector <T> tree,lazy;
    segmentTree()
    {
        tree.resize(4*N+5,inf);
        lazy.resize(4*N+5,inf);
    }
    void pushdown(int node,int l,int r)
    {
        if(lazy[node]==(T)inf)return ;
        minimize(tree[node],lazy[node]);
        if(l != r)
        {
            minimize(lazy[node<<1],lazy[node]);
            minimize(lazy[node<<1|1],lazy[node]);
        }
        lazy[node]=(T)inf;
    }
    void update(int lm,int rm,T val,int l=1,int r=n,int node=1)
    {
        pushdown(node,l,r);
        if(l > r or r < lm or l > rm)return ;
        if(lm <= l and r <= rm)
        {
            minimize(tree[node],val);
            if(l != r)
            {
                minimize(lazy[node<<1],val);
                minimize(lazy[node<<1|1],val);
            }
            return ;
        }
        int mid=(l + r)>>1;
        update(lm,rm,val,l,mid,node<<1);
        update(lm,rm,val,mid+1,r,node<<1|1);
    }
    T query(int p,int l=1,int r=n,int node=1)
    {
        pushdown(node,l,r);
        if(l > r or r < p or l > p)return (T)inf;
        if(l==r)return tree[node];
        int mid=(l + r)>>1;
        return min(query(p,l,mid,node<<1),query(p,mid+1,r,node<<1|1));
    }
};
segmentTree <int> seg;

void dfs(int u,int par)
{
    dp[u][0]=par,szt[u]=1;
    for(int i=0;i<sz(adj[u]);++i)
    {
        int v=adj[u][i].fir;
        int c=adj[u][i].sec;
        if(v == par)continue;
        d[v]=d[u] + 1;
        maxEdges[v][0]=c;
        endE[id[u][i]]=v;
        dfs(v,u);
        szt[u]+=szt[v];
    }
}

void hld(int u,int par)
{
    if(!head[nchain])head[nchain]=u;
    chainid[u]=nchain;
    pos[u]=++prt;
    int bigChild=-1;
    for(auto &i : adj[u])
    {
        int v=i.fir;
        if(v==par or v==bigChild)continue;
        if(bigChild==-1 or szt[v] > szt[bigChild])bigChild=v;
    }
    if(bigChild!=-1)hld(bigChild,u);
    for(auto &i : adj[u])
    {
        int v=i.fir;
        if(v==par or v==bigChild)continue;
        nchain++;
        hld(v,u);
    }
}

void creat()
{
    for(int j=1;j<=lg;++j)
        for(int i=1;i<=n;++i)
    {
        dp[i][j]=dp[dp[i][j-1]][j-1];
        maxEdges[i][j]=max(maxEdges[i][j-1],maxEdges[dp[i][j-1]][j-1]);
    }
}

pii lca(int u,int v)
{
    if(d[u] < d[v])swap(u,v);
    int res=-inf;
    for(int j=lg;j>=0;--j)if(d[dp[u][j]] >= d[v])maximize(res,maxEdges[u][j]),u=dp[u][j];
    if(u==v)return mp(u,res);
    for(int j=lg;j>=0;--j)if(dp[u][j] - dp[v][j])
    {
        maximize(res,maxEdges[u][j]);
        maximize(res,maxEdges[v][j]);
        u=dp[u][j],v=dp[v][j];
    }
    maximize(res,maxEdges[u][0]);
    maximize(res,maxEdges[v][0]);
    return mp(dp[u][0],res);
}

int gett(int u,int par)
{
    for(int j=lg;j>=0;--j)
        if(d[dp[u][j]] - d[par] >= 1)u=dp[u][j];
    return u;
}

void up(int u,int par,int c)
{
    if(u==par)return;
    par = gett(u,par);
    int uchain,pc=chainid[par];
    while(true)
    {
        uchain=chainid[u];
        if(uchain==pc)
        {
            seg.update(pos[par],pos[u],c);
            return ;
        }
        int headc=head[uchain];
        seg.update(pos[headc],pos[u],c);
        u=dp[headc][0];
    }
}

void solve()
{
    scanf("%d%d",&n,&m);
    for(int u,v,c,i=1;i<=m;++i)
    {
        scanf("%d%d%d",&u,&v,&c);
        edges.pb(E(u,v,c,i));
        w[i]=c;
    }
    sort(all(edges));
    for(auto &i : edges)
    {
        bool flag=dsu.join(i.u,i.v);
        if(flag)continue;
        intree[i.idx]=true;
        adj[i.u].pb(mp(i.v,i.c));
        adj[i.v].pb(mp(i.u,i.c));
        id[i.u].pb(i.idx);
        id[i.v].pb(i.idx);
    }
    dfs(1,1);
    hld(1,1);
    creat();
    fill(ans+1,ans+1+m,inf);
    for(auto &i : edges)if(!intree[i.idx])
    {
        pii lc=lca(i.u,i.v);
        ans[i.idx]=lc.sec;
        up(i.u,lc.fir,w[i.idx]);
        up(i.v,lc.fir,w[i.idx]);
    }
    for(auto &i : edges)if(intree[i.idx])
        ans[i.idx]=seg.query(pos[endE[i.idx]]);
    for(int i=1;i<=m;++i)printf("%d ",(ans[i]==inf ? -1 : --ans[i]));
}}

int main(void)
{
    #ifndef ONLINE_JUDGE
    freopen(fn".inp","r",stdin);
    freopen(fn".out","w",stdout);
    #endif // ONLINE_JUDGE
    task::solve();
}
///obitain : -ki thuat update 1 doan voi 1 gia tri min
///-ki thuat update 1 tap canh tren cay.


using namespace std;
#include<bits/stdc++.h>
#define debug(x) clog<<#x<<" = "<<x<<'\n'
#define ll long long
#define pll pair<ll,ll>
#define pii pair<int,int>
#define fir first
#define sec second
#define mp make_pair
#define pb push_back
#define sz(c) ((int)c.size())
#define all(c) (c).begin(),(c).end()
#define MASK(i) (1LL<<(i))
#define BIT(x,i) (((x)>>(i))&1)
#define fn "827D"  /// ___FILE_NAME_HERE___
#define rep(c,it) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++)
#define __rep(c,it) for(__typeof((c).rbegin()) it=(c).rbegin();it!=(c).rend();it++)

template <class T,class U>
void maximize(T &x,U y)
{
    if(x < y)x=y;
}
template <class T,class U>
void minimize(T &x,U y)
{
    if(x > y)x=y;
}
template <class T>
T Abs(T x)
{
    return (x < 0 ? -x : x);
}
template <class T>
T safe_sqrt(T x)
{
    return sqrt(max(x,(T)0));
}
template <class T,class U,class V>
T addmod(T x,U k,V MOD)
{
    return ((x+k)%MOD + MOD)%MOD;
}
template <class T,class U,class V>
T submod(T x,U k,V MOD)
{
    return ((x-k)%MOD + MOD)%MOD;
}
template <class T,class U,class V>
T mul(T x,U y,V MOD)
{
    return (ll)x*y%MOD;
}
/*------------------------------------------END_OF_TEMPLATE------------------------------------------*/

namespace task{

const int lg=18;
const int inf=2e9;
const int N=2e5+5;
vector <pii> adj[N];
vector <int> id[N];
bool intree[N];
int dp[N][lg+2],d[N],maxEdges[N][lg+2],w[N];
int head[N],pos[N],chainid[N];
int ans[N],szt[N],endE[N];
int n,m,prt=0,nchain=1;

struct E
{
    int u,v,c,idx;
    E(){}
    E(int _u,int _v,int _c,int _idx):u(_u),v(_v),c(_c),idx(_idx){}
    bool operator < (const E &other) const
    {
        return c < other.c;
    }
};
vector <E> edges;

struct Dsu
{
    vector <int> lab;
    Dsu(){lab.resize(N+5,-1);}
    int findp(int u){return lab[u] < 0 ? u : findp(lab[u]);}
    bool join(int u,int v)
    {
        u=findp(u),v=findp(v);
        if(u==v)return true;
        if(lab[u] > lab[v])swap(u,v);
        lab[u]+=lab[v],lab[v]=u;
        return false;
    }
}dsu;

template <class T> struct segmentTree
{
    vector <T> tree,lazy;
    segmentTree()
    {
        tree.resize(4*N+5,inf);
        lazy.resize(4*N+5,inf);
    }
    void pushdown(int node,int l,int r)
    {
        if(lazy[node]==inf)return ;
        minimize(tree[node],lazy[node]);
        if(l != r)
        {
            minimize(lazy[node<<1],lazy[node]);
            minimize(lazy[node<<1|1],lazy[node]);
        }
        lazy[node]=inf;
    }
    void update(int lm,int rm,T val,int l=1,int r=n,int node=1)
    {
        pushdown(node,l,r);
        if(l > r or r < lm or l > rm)return ;
        if(lm <= l and r <= rm)
        {
            minimize(tree[node],val);
            if(l != r)
            {
                minimize(lazy[node<<1],val);
                minimize(lazy[node<<1|1],val);
            }
            return ;
        }
        int mid=(l + r)>>1;
        update(lm,rm,val,l,mid,node<<1);
        update(lm,rm,val,mid+1,r,node<<1|1);
    }
    T query(int p,int l=1,int r=n,int node=1)
    {
        pushdown(node,l,r);
        if(l > r or r < p or l > p)return (T)inf;
        if(l==r)return tree[node];
        int mid=(l + r)>>1;
        return min(query(p,l,mid,node<<1),query(p,mid+1,r,node<<1|1));
    }
};
segmentTree <int> seg;

void dfs(int u,int par)
{
    dp[u][0]=par,szt[u]=1;
    for(int i=0;i<sz(adj[u]);++i)
    {
        int v=adj[u][i].fir;
        int c=adj[u][i].sec;
        if(v == par)continue;
        d[v]=d[u] + 1;
        maxEdges[v][0]=c;
        endE[id[u][i]]=v;
        dfs(v,u);
        szt[u]+=szt[v];
    }
}

void hld(int u,int par)
{
    if(!head[nchain])head[nchain]=u;
    chainid[u]=nchain;
    pos[u]=++prt;
    int bigChild=-1;
    for(auto &i : adj[u])
    {
        int v=i.fir;
        if(v==par or v==bigChild)continue;
        if(bigChild==-1 or szt[v] > szt[bigChild])bigChild=v;
    }
    if(bigChild!=-1)hld(bigChild,u);
    for(auto &i : adj[u])
    {
        int v=i.fir;
        if(v==par or v==bigChild)continue;
        nchain++;
        hld(v,u);
    }
}

void creat()
{
    for(int j=1;j<=lg;++j)
        for(int i=1;i<=n;++i)
    {
        dp[i][j]=dp[dp[i][j-1]][j-1];
        maxEdges[i][j]=max(maxEdges[i][j-1],maxEdges[dp[i][j-1]][j-1]);
    }
}

pii lca(int u,int v)
{
    if(d[u] < d[v])swap(u,v);
    int res=-inf;
    for(int j=lg;j>=0;--j)if(d[dp[u][j]] >= d[v])maximize(res,maxEdges[u][j]),u=dp[u][j];
    if(u==v)return mp(u,res);
    for(int j=lg;j>=0;--j)if(dp[u][j] - dp[v][j])
    {
        maximize(res,maxEdges[u][j]);
        maximize(res,maxEdges[v][j]);
        u=dp[u][j],v=dp[v][j];
    }
    maximize(res,maxEdges[u][0]);
    maximize(res,maxEdges[v][0]);
    return mp(dp[u][0],res);
}

void up(int u,int par,int c)
{
    int uchain,pc=chainid[par];
    while(true)
    {
        uchain=chainid[u];
        if(uchain==pc)
        {
            seg.update(pos[par],pos[u],c);
            return ;
        }
        int headc=head[uchain];
        seg.update(pos[headc],pos[u],c);
        u=dp[headc][0];
    }
}

void solve()
{
    scanf("%d%d",&n,&m);
    for(int u,v,c,i=1;i<=m;++i)
    {
        scanf("%d%d%d",&u,&v,&c);
        edges.pb(E(u,v,c,i));
        w[i]=c;
    }
    sort(all(edges));
    for(auto &i : edges)
    {
        bool flag=dsu.join(i.u,i.v);
        if(flag)continue;
        intree[i.idx]=true;
        adj[i.u].pb(mp(i.v,i.c));
        adj[i.v].pb(mp(i.u,i.c));
        id[i.u].pb(i.idx);
        id[i.v].pb(i.idx);
    }
    dfs(1,1);
    hld(1,1);
    creat();
    fill(ans+1,ans+1+m,inf);
    for(auto &i : edges)if(!intree[i.idx])
    {
        pii lc=lca(i.u,i.v);
        ans[i.idx]=lc.sec;
        up(i.u,lc.fir,w[i.idx]);
        up(i.v,lc.fir,w[i.idx]);
    }
    for(auto &i : edges)if(intree[i.idx])
        ans[i.idx]=max(seg.query(pos[i.u]),seg.query(pos[i.v]));
    for(int i=1;i<=m;++i)printf("%d ",(ans[i]==inf ? -1 : --ans[i]));
}}

int main(void)
{
    #ifndef ONLINE_JUDGE
    freopen(fn".inp","r",stdin);
    freopen(fn".out","w",stdout);
    #endif // ONLINE_JUDGE
    task::solve();
}


#include<bits/stdc++.h>
const int N = 2e5 + 5;
using namespace std;

typedef pair <int, int> ii;
typedef pair <int, ii> iii;
vector <iii> adj[N];
multiset <int> ms[2][N];
int n, m, p[N][20], Max[N][20], d[N], f[N], ans[N], pset[N];
bool ck[N];

struct edge{
    int u, v, id, w;
} e[N];

bool cmp(edge a, edge b){
    return a.w < b.w;
}

int findset(int i) {return ((pset[i] == i) ? i : pset[i] = findset(pset[i]));}

bool unionset(int i, int j){
    i = findset(i), j = findset(j);
    pset[i] = j;
    return (i != j);
}

void dfs(int u){
    for (int i = 0; i < adj[u].size(); i++){
        int v = adj[u][i].first, cost = adj[u][i].second.first, id = adj[u][i].second.second;
        if (v == p[u][0]) continue;
        p[v][0] = u; Max[v][0] = cost; d[v] = d[u]+1; f[v] = id; dfs(v);
    }
}

void preplca(){
    for (int i = 1; i < 20; i++) for (int u = 1; u <= n; u++){
        p[u][i] = p[p[u][i-1]][i-1];
        Max[u][i] = max(Max[u][i-1], Max[p[u][i-1]][i-1]);
    }
}

int getMax(int u, int v){
    int ans = 0;
    for (int i = 19; i >= 0; i--) if (d[u] - (1 << i) >= d[v]) u = p[u][i], ans = max(ans, Max[u][i]);
    for (int i = 19; i >= 0; i--) if (d[v] - (1 << i) >= d[u]) v = p[v][i], ans = max(ans, Max[v][i]);
    for (int i = 19; i >= 0; i--) if (p[u][i] != p[v][i]) u = p[u][i], v = p[v][i], ans = max(ans, Max[u][i]), ans = max(ans, Max[v][i]);
    if (u != v) ans = max(ans, Max[u][0]), ans = max(ans, Max[v][0]);
    return ans;
}

int getlca(int u, int v){
    for (int i = 19; i >= 0; i--) if (d[u] - (1 << i) >= d[v]) u = p[u][i];
    for (int i = 19; i >= 0; i--) if (d[v] - (1 << i) >= d[u]) v = p[v][i];
    for (int i = 19; i >= 0; i--) if (p[u][i] != p[v][i]) u = p[u][i], v = p[v][i];
    if (u != v) u = p[u][0];
    return u;
}

void Union(multiset<int>& a, multiset<int>& b){
    if (a.size() < b.size()) a.swap(b);
    for (int x : b) a.insert(x);
}

void del(multiset<int>& a, multiset<int>& b){
    for (int x : b) a.erase(a.lower_bound(x));
}

void redfs(int u){
    for (int i = 0; i < adj[u].size(); i++){
        int v = adj[u][i].first;
        if (v == p[u][0]) continue;
        redfs(v);
        Union(ms[0][u], ms[0][v]);
    }
    del(ms[0][u], ms[1][u]);
    if (ms[0][u].size()) ans[f[u]] = *(ms[0][u].begin());
    ans[f[u]]--;
}

int main(){
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin >> n >> m;
    for (int i = 1; i <= m; i++){
        cin >> e[i].u >> e[i].v >> e[i].w;
        e[i].id = i;
    }
    sort(e+1, e+1+m, cmp);
    for (int i = 1; i <= n; i++) pset[i] = i;
    for (int i = 1; i <= m; i++){
        if (unionset(e[i].u, e[i].v)){
            adj[e[i].u].push_back(iii(e[i].v, ii(e[i].w, e[i].id)));
            adj[e[i].v].push_back(iii(e[i].u, ii(e[i].w, e[i].id)));
            ck[i] = 1;
        }
    }
    dfs(1); preplca();
    for (int i = 1; i <= m; i++){
        if (!ck[i]){
            int p = getlca(e[i].u, e[i].v);
            ans[e[i].id] = getMax(e[i].u, e[i].v) - 1;
            ms[0][e[i].u].insert(e[i].w);
            ms[0][e[i].v].insert(e[i].w);
            ms[1][p].insert(e[i].w);
        }
    }
    redfs(1);
    for (int i = 1; i <= m; i++) cout << ans[i] << " ";
}


#include<bits/stdc++.h>
const int N = 2e5 + 5;
using namespace std;

typedef pair <int, int> ii;
typedef pair <int, ii> iii;
vector <iii> adj[N];
multiset <int> ms[2][N];
int n, m, p[N][20], Max[N][20], d[N], f[N], ans[N], pset[N];
bool ck[N];

struct edge{
    int u, v, id, w;
} e[N];

bool cmp(edge a, edge b){
    return a.w < b.w;
}

int findset(int i) {return ((pset[i] == i) ? i : pset[i] = findset(pset[i]));}

bool unionset(int i, int j){
    i = findset(i), j = findset(j);
    pset[i] = j;
    return (i != j);
}

void dfs(int u){
    for (int i = 0; i < adj[u].size(); i++){
        int v = adj[u][i].first, cost = adj[u][i].second.first, id = adj[u][i].second.second;
        if (v == p[u][0]) continue;
        p[v][0] = u; Max[v][0] = cost; d[v] = d[u]+1; f[v] = id; dfs(v);
    }
}

void preplca(){
    for (int i = 1; i < 20; i++) for (int u = 1; u <= n; u++){
        p[u][i] = p[p[u][i-1]][i-1];
        Max[u][i] = max(Max[u][i-1], Max[p[u][i-1]][i-1]);
    }
}

int getMax(int u, int v){
    int ans = 0;
    for (int i = 19; i >= 0; i--) if (d[u] - (1 << i) >= d[v]) ans = max(ans, Max[u][i]), u = p[u][i];
    for (int i = 19; i >= 0; i--) if (d[v] - (1 << i) >= d[u]) ans = max(ans, Max[v][i]), v = p[v][i];
    for (int i = 19; i >= 0; i--) if (p[u][i] != p[v][i]) ans = max(ans, Max[u][i]), ans = max(ans, Max[v][i]), u = p[u][i], v = p[v][i];
    if (u != v) ans = max(ans, Max[u][0]), ans = max(ans, Max[v][0]);
    return ans;
}

int getlca(int u, int v){
    for (int i = 19; i >= 0; i--) if (d[u] - (1 << i) >= d[v]) u = p[u][i];
    for (int i = 19; i >= 0; i--) if (d[v] - (1 << i) >= d[u]) v = p[v][i];
    for (int i = 19; i >= 0; i--) if (p[u][i] != p[v][i]) u = p[u][i], v = p[v][i];
    if (u != v) u = p[u][0];
    return u;
}

void Union(multiset<int>& a, multiset<int>& b){
    if (a.size() < b.size()) a.swap(b);
    for (int x : b) a.insert(x);
}

void del(multiset<int>& a, multiset<int>& b){
    for (int x : b) a.erase(a.lower_bound(x));
}

void redfs(int u){
    for (int i = 0; i < adj[u].size(); i++){
        int v = adj[u][i].first;
        if (v == p[u][0]) continue;
        redfs(v);
        Union(ms[0][u], ms[0][v]);
    }
    del(ms[0][u], ms[1][u]);
    if (ms[0][u].size()) ans[f[u]] = *(ms[0][u].begin());
    ans[f[u]]--;
}

int main(){
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin >> n >> m;
    for (int i = 1; i <= m; i++){
        cin >> e[i].u >> e[i].v >> e[i].w;
        e[i].id = i;
    }
    sort(e+1, e+1+m, cmp);
    for (int i = 1; i <= n; i++) pset[i] = i;
    for (int i = 1; i <= m; i++){
        if (unionset(e[i].u, e[i].v)){
            adj[e[i].u].push_back(iii(e[i].v, ii(e[i].w, e[i].id)));
            adj[e[i].v].push_back(iii(e[i].u, ii(e[i].w, e[i].id)));
            ck[i] = 1;
        }
    }
    dfs(1); preplca();
    for (int i = 1; i <= m; i++){
        if (!ck[i]){
            int p = getlca(e[i].u, e[i].v);
            ans[e[i].id] = getMax(e[i].u, e[i].v) - 1;
            ms[0][e[i].u].insert(e[i].w);
            ms[0][e[i].v].insert(e[i].w);
            ms[1][p].insert(e[i].w);
        }
    }
    redfs(1);
    for (int i = 1; i <= m; i++) cout << ans[i] << " ";
}


#include<bits/stdc++.h>
const int N = 2e5 + 5;
using namespace std;

typedef pair <int, int> ii;
typedef pair <int, ii> iii;
vector <iii> adj[N];
multiset <int> ms[2][N];
int n, m, p[N][20], Max[N][20], d[N], f[N], ans[N], pset[N];
bool ck[N];

struct edge{
    int u, v, id, w;
} e[N];

bool cmp(edge a, edge b){
    return a.w < b.w;
}

int findset(int i) {return ((pset[i] == i) ? i : pset[i] = findset(pset[i]));}

bool unionset(int i, int j){
    i = findset(i), j = findset(j);
    pset[i] = j;
    return (i != j);
}

void dfs(int u){
    for (int i = 0; i < adj[u].size(); i++){
        int v = adj[u][i].first, cost = adj[u][i].second.first, id = adj[u][i].second.second;
        if (v == p[u][0]) continue;
        p[v][0] = u; Max[v][0] = cost; d[v] = d[u]+1; f[v] = id; dfs(v);
    }
}

void preplca(){
    for (int i = 1; i < 20; i++) for (int u = 1; u <= n; u++){
        p[u][i] = p[p[u][i-1]][i-1];
        Max[u][i] = max(Max[u][i-1], Max[p[u][i-1]][i-1]);
    }
}

int getMax(int u, int v){
    int ans = 0;
    for (int i = 19; i >= 0; i--) if (d[u] - (1 << i) >= d[v]) ans = max(ans, Max[u][i]), u = p[u][i];
    for (int i = 19; i >= 0; i--) if (d[v] - (1 << i) >= d[u]) ans = max(ans, Max[v][i]), v = p[v][i];
    for (int i = 19; i >= 0; i--) if (p[u][i] != p[v][i]) ans = max(ans, Max[u][i]), ans = max(ans, Max[v][i]), u = p[u][i], v = p[v][i];
    if (u != v) ans = max(ans, Max[u][0]), ans = max(ans, Max[v][0]);
    return ans;
}

int getlca(int u, int v){
    for (int i = 19; i >= 0; i--) if (d[u] - (1 << i) >= d[v]) u = p[u][i];
    for (int i = 19; i >= 0; i--) if (d[v] - (1 << i) >= d[u]) v = p[v][i];
    for (int i = 19; i >= 0; i--) if (p[u][i] != p[v][i]) u = p[u][i], v = p[v][i];
    if (u != v) u = p[u][0];
    return u;
}

void Union(multiset<int>& a, multiset<int>& b){
    if (a.size() < b.size()) a.swap(b);
    for (int x : b) a.insert(x);
}

void del(multiset<int>& a, multiset<int>& b){
    for (int x : b) a.erase(a.lower_bound(x)), a.erase(a.lower_bound(x));
}

void redfs(int u){
    for (int i = 0; i < adj[u].size(); i++){
        int v = adj[u][i].first;
        if (v == p[u][0]) continue;
        redfs(v);
        Union(ms[0][u], ms[0][v]);
    }
    del(ms[0][u], ms[1][u]);
    if (ms[0][u].size()) ans[f[u]] = *(ms[0][u].begin());
    ans[f[u]]--;
}

int main(){
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin >> n >> m;
    for (int i = 1; i <= m; i++){
        cin >> e[i].u >> e[i].v >> e[i].w;
        e[i].id = i;
    }
    sort(e+1, e+1+m, cmp);
    for (int i = 1; i <= n; i++) pset[i] = i;
    for (int i = 1; i <= m; i++){
        if (unionset(e[i].u, e[i].v)){
            adj[e[i].u].push_back(iii(e[i].v, ii(e[i].w, e[i].id)));
            adj[e[i].v].push_back(iii(e[i].u, ii(e[i].w, e[i].id)));
            ck[i] = 1;
        }
    }
    dfs(1); preplca();
    for (int i = 1; i <= m; i++){
        if (!ck[i]){
            int p = getlca(e[i].u, e[i].v);
            ans[e[i].id] = getMax(e[i].u, e[i].v) - 1;
            ms[0][e[i].u].insert(e[i].w);
            ms[0][e[i].v].insert(e[i].w);
            ms[1][p].insert(e[i].w);
        }
    }
    redfs(1);
    for (int i = 1; i <= m; i++) cout << ans[i] << " ";
}


#include <iostream>
#include <cstdio>
#include <vector>
#include <ctime>
#include <cstdlib>
#include <unistd.h>
#include <algorithm>
#include <map>
#include <set>
using namespace std;

#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define REP(i, n) FOR(i, 0, n)
#define TRACE(x) cout << #x << " = " << x << endl

typedef pair<int, int> par;

#define X first
#define Y second

const int MAXN = 2e5 + 10, LOG = 19, INF = 1e9 + 10;

struct brid {
  int a, b, c;
  brid(int _a = 0, int _b = 0, int _c = 0) {
    a = _a;
    b = _b;
    c = _c;
  }
} bridovi[MAXN];

int cmp(brid x, brid y) {
  if(x.c != y.c) return x.c < y.c;
  if(x.a != y.a) return x.a < y.a;
  return x.b < y.b;
}

int n, m;
int tata[MAXN], dubina[MAXN], indeks[MAXN];
int anc[LOG][MAXN], cijena[LOG][MAXN];

vector<int> dodaj[MAXN], makni[MAXN], stablo[MAXN];

vector<par> unos;
vector<par> graf[MAXN];

map<par, int> mst, rj;

multiset<int> s[MAXN];

int union_find(int x) {
  if(tata[x] == x) return x;
  return tata[x] = union_find(tata[x]);
}

void spoji(int a, int b) {
  a = union_find(a), b = union_find(b);
  if(rand() % 2)
    tata[a] = b;
  else
    tata[b] = a;
}

void dfs(int cvor, int prije, int d) {
  dubina[cvor] = d;
  REP(i, (int) graf[cvor].size()) {
    if(graf[cvor][i].X == prije) continue;
    if(!mst[par(cvor, graf[cvor][i].X)]) continue;
    stablo[cvor].push_back(graf[cvor][i].X);
    anc[0][graf[cvor][i].X] = cvor;
    cijena[0][graf[cvor][i].X] = graf[cvor][i].Y;
    dfs(graf[cvor][i].X, cvor, d + 1);
  }
}

void dinamika() {
  cijena[0][1] = -INF;
  FOR(i, 1, LOG)
    FOR(j, 1, n + 1) {
      anc[i][j] = anc[i - 1][anc[i - 1][j]];
      cijena[i][j] = max(cijena[i - 1][j], cijena[i - 1][anc[i - 1][j]]);
    }
}

par digni(int x, int k) {
  int ret = -INF;
  REP(i, LOG)
    if(k & (1 << i)) {
      ret = max(ret, cijena[k][x]);
      x = anc[k][x];
    }
  return par(x, ret);
}

int prvi_query(int a, int b) {
  int ret = -INF;
  if(dubina[a] > dubina[b]) {
    par t = digni(a, dubina[a] - dubina[b]);
    a = t.X;
    ret = t.Y;
  }
  else if(dubina[b] > dubina[a]) {
    par t = digni(b, dubina[b] - dubina[a]);
    b = t.X;
    ret = t.Y;
  }
  for(int i = LOG - 1; i >= 0; i--) {
    if(anc[i][a] == anc[i][b]) continue;
    ret = max(ret, cijena[i][a]);
    ret = max(ret, cijena[i][b]);
    a = anc[i][a];
    b = anc[i][b];
  }
  ret = max(ret, cijena[0][a]);
  ret = max(ret, cijena[0][b]);
  return ret;
}

int LCA(int a, int b) {
  if(dubina[a] > dubina[b]) a = digni(a, dubina[a] - dubina[b]).X;
  if(dubina[b] > dubina[a]) b = digni(b, dubina[b] - dubina[a]).X;
  for(int i = LOG - 1; i >= 0; i--) {
    if(anc[i][a] == anc[i][b]) continue;
    a = anc[i][a];
    b = anc[i][b];
  }
  a = anc[0][a];
  return a;
}

void merge(int a, int b) {
  if(s[indeks[a]].size() > s[indeks[b]].size()) swap(a, b);
  multiset<int> :: iterator it;
  for(it = s[indeks[a]].begin(); it != s[indeks[a]].end(); it++)
    s[indeks[b]].insert(*it);
  indeks[a] = indeks[b];
}

void rek(int cvor, int prije) {
  REP(i, (int) stablo[cvor].size()) rek(stablo[cvor][i], cvor);
  REP(i, (int) stablo[cvor].size()) merge(cvor, stablo[cvor][i]);
  REP(i, (int) dodaj[cvor].size()) s[indeks[cvor]].insert(dodaj[cvor][i]);
  REP(i, (int) makni[cvor].size()) s[indeks[cvor]].erase(s[indeks[cvor]].find(makni[cvor][i]));
  rj[par(cvor, prije)] = rj[par(prije, cvor)] = *s[indeks[cvor]].begin();
}

int main() {
  srand(time(0) * getpid());
  scanf("%d %d", &n, &m);
  REP(i, m) {
    int a, b, c;
    scanf("%d %d %d", &a, &b, &c);
    graf[a].push_back(par(b, c));
    graf[b].push_back(par(a, c));
    bridovi[i] = brid(a, b, c);
    unos.push_back(par(a, b));
  }
  sort(bridovi, bridovi + n, cmp);
  FOR(i, 1, n + 1) tata[i] = i;
  REP(i, n) {
    brid sad = bridovi[i];
    int a = union_find(sad.a);
    int b = union_find(sad.b);
    if(a == b) continue;
    mst[par(sad.a, sad.b)] = mst[par(sad.b, sad.a)] = 1;
    spoji(sad.a, sad.b);
  }
  dfs(1, -1, 1);
  dinamika();
  REP(i, n) {
    if(mst[par(bridovi[i].a, bridovi[i].b)]) continue;
    int lca = LCA(bridovi[i].a, bridovi[i].b);
    dodaj[bridovi[i].a].push_back(bridovi[i].c);
    dodaj[bridovi[i].b].push_back(bridovi[i].c);
    REP(j, 2) makni[lca].push_back(bridovi[i].c);
  }
  FOR(i, 1, n + 1) s[i].insert(INF);
  REP(i, n + 1) indeks[i] = i;
  rek(1, 0);
  REP(i, m) {
    int a = unos[i].X, b = unos[i].Y;
    int ispis;
    if(!mst[par(a, b)]) ispis = prvi_query(a, b);
    else ispis = rj[par(a, b)];
    if(ispis == INF) ispis = 0;
    ispis--;
    printf("%d ", ispis);
  }
  return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#include <ctime>
#include <cstdlib>
#include <unistd.h>
#include <algorithm>
#include <map>
#include <set>
using namespace std;

#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define REP(i, n) FOR(i, 0, n)
#define TRACE(x) cout << #x << " = " << x << endl

typedef pair<int, int> par;

#define X first
#define Y second

const int MAXN = 2e5 + 10, LOG = 19, INF = 1e9 + 10;

struct brid {
  int a, b, c;
  brid(int _a = 0, int _b = 0, int _c = 0) {
    a = _a;
    b = _b;
    c = _c;
  }
} bridovi[MAXN];

int cmp(brid x, brid y) {
  if(x.c != y.c) return x.c < y.c;
  if(x.a != y.a) return x.a < y.a;
  return x.b < y.b;
}

int n, m;
int tata[MAXN], dubina[MAXN], indeks[MAXN];
int anc[LOG][MAXN], cijena[LOG][MAXN];

vector<int> dodaj[MAXN], makni[MAXN], stablo[MAXN];

vector<par> unos;
vector<par> graf[MAXN];

map<par, int> mst, rj;

multiset<int> s[MAXN];

int union_find(int x) {
  if(tata[x] == x) return x;
  return tata[x] = union_find(tata[x]);
}

void spoji(int a, int b) {
  a = union_find(a), b = union_find(b);
  if(rand() % 2)
    tata[a] = b;
  else
    tata[b] = a;
}

void dfs(int cvor, int prije, int d) {
  dubina[cvor] = d;
  REP(i, (int) graf[cvor].size()) {
    if(graf[cvor][i].X == prije) continue;
    if(!mst[par(cvor, graf[cvor][i].X)]) continue;
    stablo[cvor].push_back(graf[cvor][i].X);
    anc[0][graf[cvor][i].X] = cvor;
    cijena[0][graf[cvor][i].X] = graf[cvor][i].Y;
    dfs(graf[cvor][i].X, cvor, d + 1);
  }
}

void dinamika() {
  cijena[0][1] = -INF;
  FOR(i, 1, LOG)
    FOR(j, 1, n + 1) {
      anc[i][j] = anc[i - 1][anc[i - 1][j]];
      cijena[i][j] = max(cijena[i - 1][j], cijena[i - 1][anc[i - 1][j]]);
    }
}

par digni(int x, int k) {
  int ret = -INF;
  REP(i, LOG)
    if(k & (1 << i)) {
      ret = max(ret, cijena[i][x]);
      x = anc[i][x];
    }
  return par(x, ret);
}

int prvi_query(int a, int b) {
  int ret = -INF;
  if(dubina[a] > dubina[b]) {
    par t = digni(a, dubina[a] - dubina[b]);
    a = t.X;
    ret = t.Y;
  }
  else if(dubina[b] > dubina[a]) {
    par t = digni(b, dubina[b] - dubina[a]);
    b = t.X;
    ret = t.Y;
  }
  if(a == b) return ret;
  for(int i = LOG - 1; i >= 0; i--) {
    if(anc[i][a] == anc[i][b]) continue;
    ret = max(ret, cijena[i][a]);
    ret = max(ret, cijena[i][b]);
    a = anc[i][a];
    b = anc[i][b];
  }
  ret = max(ret, cijena[0][a]);
  ret = max(ret, cijena[0][b]);
  return ret;
}

int LCA(int a, int b) {
  if(dubina[a] > dubina[b]) a = digni(a, dubina[a] - dubina[b]).X;
  else if(dubina[b] > dubina[a]) b = digni(b, dubina[b] - dubina[a]).X;
  if(a == b) return a;
  for(int i = LOG - 1; i >= 0; i--) {
    if(anc[i][a] == anc[i][b]) continue;
    a = anc[i][a];
    b = anc[i][b];
  }
  a = anc[0][a];
  return a;
}

void merge(int a, int b) {
  if(s[indeks[a]].size() > s[indeks[b]].size()) swap(a, b);
  multiset<int> :: iterator it;
  for(it = s[indeks[a]].begin(); it != s[indeks[a]].end(); it++)
    s[indeks[b]].insert(*it);
  indeks[a] = indeks[b];
}

void rek(int cvor, int prije) {
  REP(i, (int) stablo[cvor].size()) rek(stablo[cvor][i], cvor);
  REP(i, (int) stablo[cvor].size()) merge(cvor, stablo[cvor][i]);
  REP(i, (int) dodaj[cvor].size()) s[indeks[cvor]].insert(dodaj[cvor][i]);
  REP(i, (int) makni[cvor].size()) s[indeks[cvor]].erase(s[indeks[cvor]].find(makni[cvor][i]));
  rj[par(cvor, prije)] = rj[par(prije, cvor)] = *s[indeks[cvor]].begin();
}

int main() {
  srand(time(0) * getpid());
  scanf("%d %d", &n, &m);
  REP(i, m) {
    int a, b, c;
    scanf("%d %d %d", &a, &b, &c);
    graf[a].push_back(par(b, c));
    graf[b].push_back(par(a, c));
    bridovi[i] = brid(a, b, c);
    unos.push_back(par(a, b));
  }
  sort(bridovi, bridovi + m, cmp);
  FOR(i, 1, n + 1) tata[i] = i;
  REP(i, m) {
    brid sad = bridovi[i];
    int a = union_find(sad.a);
    int b = union_find(sad.b);
    if(a == b) continue;
    mst[par(sad.a, sad.b)] = mst[par(sad.b, sad.a)] = 1;
    spoji(sad.a, sad.b);
  }
  dfs(1, -1, 1);
  dinamika();
  REP(i, m) {
    if(mst[par(bridovi[i].a, bridovi[i].b)]) continue;
    int lca = LCA(bridovi[i].a, bridovi[i].b);
    dodaj[bridovi[i].a].push_back(bridovi[i].c);
    dodaj[bridovi[i].b].push_back(bridovi[i].c);
    REP(j, 2) makni[lca].push_back(bridovi[i].c);
  }
  FOR(i, 1, n + 1) s[i].insert(INF);
  REP(i, n + 1) indeks[i] = i;
  rek(1, 0);
  REP(i, m) {
    int a = unos[i].X, b = unos[i].Y;
    int ispis;
    if(!mst[par(a, b)]) ispis = prvi_query(a, b);
    else ispis = rj[par(a, b)];
    if(ispis == INF) ispis = 0;
    ispis--;
    printf("%d ", ispis);
  }
  printf("\n");
  return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#include <ctime>
#include <cstdlib>
#include <unistd.h>
#include <algorithm>
#include <map>
#include <set>
using namespace std;

#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define REP(i, n) FOR(i, 0, n)
#define TRACE(x) cout << #x << " = " << x << endl

typedef pair<int, int> par;

#define X first
#define Y second

const int MAXN = 2e5 + 10, LOG = 19, INF = 1e9 + 10;

struct brid {
  int a, b, c;
  brid(int _a = 0, int _b = 0, int _c = 0) {
    a = _a;
    b = _b;
    c = _c;
  }
} bridovi[MAXN];

int cmp(brid x, brid y) {
  if(x.c != y.c) return x.c < y.c;
  if(x.a != y.a) return x.a < y.a;
  return x.b < y.b;
}

int n, m;
int tata[MAXN], dubina[MAXN], indeks[MAXN];
int anc[LOG][MAXN], cijena[LOG][MAXN];

vector<int> dodaj[MAXN], makni[MAXN], stablo[MAXN];

vector<par> unos;
vector<par> graf[MAXN];

map<par, int> mst, rj;

multiset<int> s[MAXN];

int union_find(int x) {
  if(tata[x] == x) return x;
  return tata[x] = union_find(tata[x]);
}

void spoji(int a, int b) {
  a = union_find(a), b = union_find(b);
  if(rand() % 2)
    tata[a] = b;
  else
    tata[b] = a;
}

void dfs(int cvor, int prije, int d) {
  dubina[cvor] = d;
  REP(i, (int) graf[cvor].size()) {
    if(graf[cvor][i].X == prije) continue;
    if(!mst[par(cvor, graf[cvor][i].X)]) continue;
    stablo[cvor].push_back(graf[cvor][i].X);
    anc[0][graf[cvor][i].X] = cvor;
    cijena[0][graf[cvor][i].X] = graf[cvor][i].Y;
    dfs(graf[cvor][i].X, cvor, d + 1);
  }
}

void dinamika() {
  cijena[0][1] = -INF;
  FOR(i, 1, LOG)
    FOR(j, 1, n + 1) {
      anc[i][j] = anc[i - 1][anc[i - 1][j]];
      cijena[i][j] = max(cijena[i - 1][j], cijena[i - 1][anc[i - 1][j]]);
    }
}

par digni(int x, int k) {
  int ret = -INF;
  REP(i, LOG)
    if(k & (1 << i)) {
      ret = max(ret, cijena[k][x]);
      x = anc[k][x];
    }
  return par(x, ret);
}

int prvi_query(int a, int b) {
  int ret = -INF;
  if(dubina[a] > dubina[b]) {
    par t = digni(a, dubina[a] - dubina[b]);
    a = t.X;
    ret = t.Y;
  }
  else if(dubina[b] > dubina[a]) {
    par t = digni(b, dubina[b] - dubina[a]);
    b = t.X;
    ret = t.Y;
  }
  for(int i = LOG - 1; i >= 0; i--) {
    if(anc[i][a] == anc[i][b]) continue;
    ret = max(ret, cijena[i][a]);
    ret = max(ret, cijena[i][b]);
    a = anc[i][a];
    b = anc[i][b];
  }
  ret = max(ret, cijena[0][a]);
  ret = max(ret, cijena[0][b]);
  return ret;
}

int LCA(int a, int b) {
  if(dubina[a] > dubina[b]) a = digni(a, dubina[a] - dubina[b]).X;
  if(dubina[b] > dubina[a]) b = digni(b, dubina[b] - dubina[a]).X;
  for(int i = LOG - 1; i >= 0; i--) {
    if(anc[i][a] == anc[i][b]) continue;
    a = anc[i][a];
    b = anc[i][b];
  }
  a = anc[0][a];
  return a;
}

void merge(int a, int b) {
  if(s[indeks[a]].size() > s[indeks[b]].size()) swap(a, b);
  multiset<int> :: iterator it;
  for(it = s[indeks[a]].begin(); it != s[indeks[a]].end(); it++)
    s[indeks[b]].insert(*it);
  indeks[a] = indeks[b];
}

void rek(int cvor, int prije) {
  REP(i, (int) stablo[cvor].size()) rek(stablo[cvor][i], cvor);
  REP(i, (int) stablo[cvor].size()) merge(cvor, stablo[cvor][i]);
  REP(i, (int) dodaj[cvor].size()) s[indeks[cvor]].insert(dodaj[cvor][i]);
  REP(i, (int) makni[cvor].size()) s[indeks[cvor]].erase(s[indeks[cvor]].find(makni[cvor][i]));
  rj[par(cvor, prije)] = rj[par(prije, cvor)] = *s[indeks[cvor]].begin();
}

int main() {
  srand(time(0) * getpid());
  scanf("%d %d", &n, &m);
  REP(i, m) {
    int a, b, c;
    scanf("%d %d %d", &a, &b, &c);
    graf[a].push_back(par(b, c));
    graf[b].push_back(par(a, c));
    bridovi[i] = brid(a, b, c);
    unos.push_back(par(a, b));
  }
  sort(bridovi, bridovi + m, cmp);
  FOR(i, 1, n + 1) tata[i] = i;
  REP(i, m) {
    brid sad = bridovi[i];
    int a = union_find(sad.a);
    int b = union_find(sad.b);
    if(a == b) continue;
    mst[par(sad.a, sad.b)] = mst[par(sad.b, sad.a)] = 1;
    spoji(sad.a, sad.b);
  }
  dfs(1, -1, 1);
  dinamika();
  REP(i, m) {
    if(mst[par(bridovi[i].a, bridovi[i].b)]) continue;
    int lca = LCA(bridovi[i].a, bridovi[i].b);
    dodaj[bridovi[i].a].push_back(bridovi[i].c);
    dodaj[bridovi[i].b].push_back(bridovi[i].c);
    REP(j, 2) makni[lca].push_back(bridovi[i].c);
  }
  FOR(i, 1, n + 1) s[i].insert(INF);
  REP(i, n + 1) indeks[i] = i;
  rek(1, 0);
  REP(i, m) {
    int a = unos[i].X, b = unos[i].Y;
    int ispis;
    if(!mst[par(a, b)]) ispis = prvi_query(a, b);
    else ispis = rj[par(a, b)];
    if(ispis == INF) ispis = 0;
    ispis--;
    printf("%d ", ispis);
  }
  return 0;
}


#include "bits/stdc++.h"
using namespace std;
const int maxn = 200200;
const int inf = 1<<30;
int tree[maxn<<2], lazy[maxn<<2];
void push(int id, int l, int r){
	if(lazy[id]){
		tree[id] = min(tree[id], lazy[id]);
		if(l != r){
			lazy[id + id] = min(lazy[id + id], lazy[id]);
			lazy[id + id + 1] = min(lazy[id + id + 1], lazy[id]);
		}
		lazy[id]  = 0;
	}
}
int x, y, TO;
void update(int id, int l, int r){
	push(id, l, r);
	if(r < x || l > y) return;
	if(x <= l && r <= y){
		lazy[id] = TO;
		push(id, l, r);
		return;
	}
	int mid = (l + r) >> 1;
	update(id + id, l, mid);
	update(id + id + 1, mid + 1, r);
	tree[id] = min(tree[id + id], tree[id + id + 1]);
}
int get(int id, int l, int r){
	push(id, l, r);
	if(r < x || l > y) return inf;
	if(x <= l && r <= y) return tree[id];
	int mid = (l + r) >> 1;
	return min(get(id + id, l, mid), get(id + id + 1, mid + 1, r));
}
int nxt[maxn], in[maxn], sz[maxn], T, depth[maxn], parent[maxn];
vector<int> g[maxn];
void dfs(int cur, int p){
	parent[cur] = p;
	sz[cur] = 1;
	for(int &v:g[cur]) if(v != p){
		depth[v] = depth[cur] + 1;
		dfs(v, cur);
		sz[cur] += sz[v];
		if(sz[v] > sz[g[cur][0]] || g[cur][0] == p)
			swap(g[cur][0], v);
	}
}
void init(int cur, int p){
	in[cur] = T++;
	for(int v : g[cur]) if (v != p){
		nxt[v] = (v == g[cur][0])?nxt[cur]:v;
		init(v, cur);
	}
}
void update(int from, int to){
	while(nxt[from] != nxt[to]){
		fprintf(stderr, "%d %d\n", from, to);
		if(depth[parent[nxt[from]]] < depth[parent[nxt[to]]])
			swap(from, to);
		x = in[nxt[from]]; y = nxt[from];
		update(1, 0, T);
		from = parent[nxt[from]];
	}
	if(in[from] > in[to])
		swap(from, to);
	if(in[from] + 1 <= in[to]){
		x = in[from] + 1; y = in[to];
		update(1, 0, T);
	}
}
int query(int from, int to){
	// fprintf(stderr, "%d -> %d : %d\n", from, to, 0);
	int heavy = inf;
	while(nxt[from] != nxt[to]){
		fprintf(stderr, "%d %d\n", from, to);
		if(depth[parent[nxt[from]]] < depth[parent[nxt[to]]])
			swap(from, to);
		x = in[nxt[from]]; y = nxt[from];
		heavy = min(heavy, get(1, 0, T) );
		from = parent[nxt[from]];
	}
	// fprintf(stderr, "%d -> %d : %d\n", from, to, 1);
	if(in[from] > in[to])
		swap(from, to);
	if(in[from] + 1 <= in[to]){
		x = in[from] + 1; y = in[to];
		heavy = min(heavy, get(1, 0, T) );
	}
	return heavy;
}
int dad[maxn], mark[maxn], ans[maxn];
int find(int x){
    return (x == dad[x])?x:dad[x] = find(dad[x]);
}
int main(){
	int n, m;
	scanf("%d %d", &n, &m);
	vector<pair<int, int> > edges, dsu;
	for(int e = 0; e < m; e++){
		int from, to, cost;
		scanf("%d %d %d", &from, &to, &cost);
		from--; to--;
		edges.push_back({from, to});
		dsu.push_back({cost, e});
	}
	for(int e = 0; e < maxn; e++)
		dad[e] = e;
	sort(dsu.begin(), dsu.end());
	for(int e = 0; e < m; e++){
		int u, v; tie(u, v) = edges[dsu[e].second];
		if(find(u) != find(v)){
			// fprintf(stderr, "(%d, %d)\n", u, v);
			g[u].push_back(v);
			g[v].push_back(u);
			mark[dsu[e].second] = 1;
			dad[find(u)] = find(v);
		}
	}
	for(int e = 0; e < 4*maxn; e++) tree[e] = inf, lazy[e] = 0;
	// fprintf(stderr, "ah\n");
	dfs(0, maxn-1);
	init(0, maxn-1);
	depth[maxn-1] = -1;
	// fprintf(stderr, "%d %d\n", parent[nxt[0]], parent[nxt[4]]);
	// return 0;
	for(int e = 0; e < m; e++){
		int ed, cost; tie(cost, ed) = dsu[e];
		int u, v; tie(u, v) = edges[ed];
		if(mark[ed]){
			if(depth[u] < depth[v]) swap(u, v);
			x = in[u]; y = in[u]; TO = cost;
			update(1, 0, T);
			// fprintf(stderr, "%d -> %d :: %d = %d\n", u, v, cost, get(1, 0, T));
		}
	}
	for(int e = 0; e < m; e++){
		int ed, cost; tie(cost, ed) = dsu[e];
		int u, v; tie(u, v) = edges[ed];
		if(!mark[ed]){
			ans[ed] = query(u, v) - 1;
			// query(u, v);
			// fprintf(stderr, "%d -> %d : %d\n", u, v, query(u, v));
		}
	}
	for(int e = 0; e < 4*maxn; e++) tree[e] = inf, lazy[e] = 0;
	for(int e = 0; e < m; e++){
		int ed, cost; tie(cost, ed) = dsu[e];
		int u, v; tie(u, v) = edges[ed];
		TO = cost;
		if(!mark[ed])
			update(u, v);
	}
	for(int e = 0; e < m; e++){
		int ed, cost; tie(cost, ed) = dsu[e];
		int u, v; tie(u, v) = edges[ed];
		if(mark[ed])
			ans[ed] = query(u, v) - 1;
	}
	for(int e = 0; e < m; e++)
		if(ans[e] == inf - 1)
			ans[e] = -1;
	for(int e = 0; e < m; e++)
		printf("%d ", ans[e]);
	printf("\n");
	return 0;
}


#include "bits/stdc++.h"
using namespace std;
const int maxn = 200200;
const int inf = 1<<30;
int tree[maxn<<2], lazy[maxn<<2];
void push(int id, int l, int r){
	if(lazy[id] != inf){
		tree[id] = min(tree[id], lazy[id]);
		if(l != r){
			lazy[id + id] = min(lazy[id + id], lazy[id]);
			lazy[id + id + 1] = min(lazy[id + id + 1], lazy[id]);
		}
		lazy[id]  = inf;
	}
}
int x, y, TO;
void update(int id, int l, int r){
	push(id, l, r);
	if(r < x || l > y) return;
	if(x <= l && r <= y){
		lazy[id] = TO;
		push(id, l, r);
		return;
	}
	int mid = (l + r) >> 1;
	update(id + id, l, mid);
	update(id + id + 1, mid + 1, r);
	tree[id] = min(tree[id + id], tree[id + id + 1]);
}
int get(int id, int l, int r){
	push(id, l, r);
	if(r < x || l > y) return inf;
	if(x <= l && r <= y) return tree[id];
	int mid = (l + r) >> 1;
	return min(get(id + id, l, mid), get(id + id + 1, mid + 1, r));
}
int nxt[maxn], in[maxn], sz[maxn], T, depth[maxn], parent[maxn];
vector<int> g[maxn];
void dfs(int cur, int p){
	parent[cur] = p;
	sz[cur] = 1;
	for(int &v:g[cur]) if(v != p){
		depth[v] = depth[cur] + 1;
		dfs(v, cur);
		sz[cur] += sz[v];
		if(sz[v] > sz[g[cur][0]] || g[cur][0] == p)
			swap(g[cur][0], v);
	}
}
void init(int cur, int p){
	in[cur] = T++;
	for(int v : g[cur]) if (v != p){
		nxt[v] = (v == g[cur][0])?nxt[cur]:v;
		init(v, cur);
	}
}
void update(int from, int to){
	while(nxt[from] != nxt[to]){
		// fprintf(stderr, "%d %d\n", from, to);
		if(depth[nxt[from]] < depth[nxt[to]])
			swap(from, to);
		x = in[nxt[from]]; y = in[from];
		update(1, 0, T);
		from = parent[nxt[from]];
	}
	if(depth[from] > depth[to])
		swap(from, to);
	if(from != to){
		// printf("add %d %d %d\n", from, to, TO);
		x = in[from] + 1; y = in[to];
		update(1, 0, T);
		x = in[17]; y = in[17];
		// printf("get %d\n", get(1, 0, T));
	}
}
int query(int from, int to){
	// fprintf(stderr, "%d -> %d : %d\n", from, to, 0);
	int heavy = inf;
	while(nxt[from] != nxt[to]){
		// fprintf(stderr, "%d %d\n", from, to);
		if(depth[nxt[from]] < depth[nxt[to]])
			swap(from, to);
		x = in[nxt[from]]; y = in[from];
		heavy = min(heavy, get(1, 0, T) );
		from = parent[nxt[from]];
	}
	// fprintf(stderr, "%d -> %d : %d\n", from, to, 1);
	if(depth[from] > depth[to])
		swap(from, to);
	if(from != to){
		x = in[from] + 1; y = in[to];
		heavy = min(heavy, get(1, 0, T) );
	}
	return heavy;
}

int dad[maxn], mark[maxn], ans[maxn];
int find(int x){
    return (x == dad[x])?x:dad[x] = find(dad[x]);
}
const int lg = 22;
int lca[lg][maxn], w[lg][maxn];
int getLca(int u, int v){
	if(depth[u] < depth[v]) swap(u, v);
	for(int e = lg-1; e >= 0; e--)
		if((depth[u] - depth[v])&(1<<e))
			u = lca[e][u];
	if(u == v) return u;
	for(int e = lg-1; e >= 0; e--)
		if(lca[e][u] != lca[e][v])
			u = lca[e][u],
			v = lca[e][v];
	return lca[0][u];
}
int getW(int u, int lc){
	int ans = 0;
	for(int e = lg-1; e >= 0; e--){
		if((depth[u] - depth[lc])&(1<<e)){
			ans = max(ans, w[e][u]);
			u = lca[e][u];
		}
	}
	return ans;
}
int main(){
	int n, m;
	scanf("%d %d", &n, &m);
	vector<pair<int, int> > edges, dsu;
	for(int e = 0; e < m; e++){
		int from, to, cost;
		scanf("%d %d %d", &from, &to, &cost);
		from--; to--;
		edges.push_back({from, to});
		dsu.push_back({cost, e});
	}
	for(int e = 0; e < maxn; e++)
		dad[e] = e;
	sort(dsu.begin(), dsu.end());
	for(int e = 0; e < m; e++){
		int u, v; tie(u, v) = edges[dsu[e].second];
		if(find(u) != find(v)){
			// fprintf(stderr, "(%d, %d)\n", u, v);
			g[u].push_back(v);
			g[v].push_back(u);
			mark[dsu[e].second] = 1;
			dad[find(u)] = find(v);
		}
	}
	// fprintf(stderr, "ah\n");
	dfs(0, maxn-1);
	init(0, maxn-1);
	depth[maxn-1] = -1;
	// fprintf(stderr, "%d %d\n", parent[nxt[0]], parent[nxt[4]]);
	// return 0;
	for(int e = 0; e < m; e++){
		int ed, cost; tie(cost, ed) = dsu[e];
		int u, v; tie(u, v) = edges[ed];
		if(mark[ed]){
			if(depth[u] < depth[v]) swap(u, v);
			w[0][u] = cost;
		}
	}
	for(int e = 0; e < n; e++)
		lca[0][e] = parent[e];
	for(int f = 1; f < lg; f++)
		for(int e = 0; e <= n; e++)
			if(lca[f-1][e] != maxn-1){
				lca[f][e] = lca[f-1][lca[f-1][e]];
				w[f][e] = max(w[f-1][e], w[f-1][lca[f-1][e]]);
			}
	// for(int f = 0; f < lg; f++){
	// 	printf("(%d): ", f);
	// 	for(int e = 0; e < n; e++)
	// 		printf("%d%c", w[f][e] , " \n"[e == n-1]);
	// }
	for(int e = 0; e < m; e++){
		int ed, cost; tie(cost, ed) = dsu[e];
		int u, v; tie(u, v) = edges[ed];
		if(!mark[ed]){
			int lc = getLca(u, v);
			ans[ed] = max(getW(u, lc), getW(v, lc)) - 1;
			// printf("(%d, %d)\n", ed, getW(3, 0));
		}
	}
	for(int e = 0; e < 4*maxn; e++) tree[e] = inf, lazy[e] = inf;
	for(int e = 0; e < m; e++){
		int ed, cost; tie(cost, ed) = dsu[e];
		int u, v; tie(u, v) = edges[ed];
		TO = cost;
		if(!mark[ed]){
			update(u, v);
		}
	}
	for(int e = 0; e < m; e++){
		int ed, cost; tie(cost, ed) = dsu[e];
		int u, v; tie(u, v) = edges[ed];
		x = max(in[u], in[v]);
		y = x;
		if(mark[ed])
			ans[ed] = get(1, 0, T) - 1;
	}
	for(int e = 0; e < m; e++)
		if(ans[e] == inf - 1)
			ans[e] = -1;
	for(int e = 0; e < m; e++)
		printf("%d ", ans[e]);
	printf("\n");
	return 0;
}


#include "bits/stdc++.h"
using namespace std;
const int maxn = 200200;
const int inf = 1<<30;
int tree[maxn<<2], lazy[maxn<<2];
void push(int id, int l, int r){
	if(lazy[id]){
		tree[id] = min(tree[id], lazy[id]);
		if(l != r){
			lazy[id + id] = min(lazy[id + id], lazy[id]);
			lazy[id + id + 1] = min(lazy[id + id + 1], lazy[id]);
		}
		lazy[id]  = 0;
	}
}
int x, y, TO;
void update(int id, int l, int r){
	push(id, l, r);
	if(r < x || l > y) return;
	if(x <= l && r <= y){
		lazy[id] = TO;
		push(id, l, r);
		return;
	}
	int mid = (l + r) >> 1;
	update(id + id, l, mid);
	update(id + id + 1, mid + 1, r);
	tree[id] = min(tree[id + id], tree[id + id + 1]);
}
int get(int id, int l, int r){
	push(id, l, r);
	if(r < x || l > y) return inf;
	if(x <= l && r <= y) return tree[id];
	int mid = (l + r) >> 1;
	return min(get(id + id, l, mid), get(id + id + 1, mid + 1, r));
}
int nxt[maxn], in[maxn], sz[maxn], T, depth[maxn], parent[maxn];
vector<int> g[maxn];
void dfs(int cur, int p){
	parent[cur] = p;
	sz[cur] = 1;
	for(int &v:g[cur]) if(v != p){
		depth[v] = depth[cur] + 1;
		dfs(v, cur);
		sz[cur] += sz[v];
		if(sz[v] > sz[g[cur][0]] || g[cur][0] == p)
			swap(g[cur][0], v);
	}
}
void init(int cur, int p){
	in[cur] = T++;
	for(int v : g[cur]) if (v != p){
		nxt[v] = (v == g[cur][0])?nxt[cur]:v;
		init(v, cur);
	}
}
void update(int from, int to){
	while(nxt[from] != nxt[to]){
		// fprintf(stderr, "%d %d\n", from, to);
		if(depth[nxt[from]] < depth[nxt[to]])
			swap(from, to);
		x = in[nxt[from]]; y = in[from];
		update(1, 0, T);
		from = parent[nxt[from]];
	}
	if(in[from] > in[to])
		swap(from, to);
	if(in[from] + 1 <= in[to]){
		x = in[from] + 1; y = in[to];
		update(1, 0, T);
	}
}
int query(int from, int to){
	// fprintf(stderr, "%d -> %d : %d\n", from, to, 0);
	int heavy = inf;
	while(nxt[from] != nxt[to]){
		fprintf(stderr, "%d %d\n", from, to);
		if(depth[nxt[from]] < depth[nxt[to]])
			swap(from, to);
		x = in[nxt[from]]; y = in[from];
		heavy = min(heavy, get(1, 0, T) );
		from = parent[nxt[from]];
	}
	// fprintf(stderr, "%d -> %d : %d\n", from, to, 1);
	if(in[from] > in[to])
		swap(from, to);
	if(in[from] + 1 <= in[to]){
		x = in[from] + 1; y = in[to];
		heavy = min(heavy, get(1, 0, T) );
	}
	return heavy;
}

int dad[maxn], mark[maxn], ans[maxn];
int find(int x){
    return (x == dad[x])?x:dad[x] = find(dad[x]);
}
const int lg = 22;
int lca[lg][maxn], w[lg][maxn];
int getLca(int u, int v){
	if(depth[u] < depth[v]) swap(u, v);
	for(int e = lg-1; e >= 0; e--)
		if((depth[u] - depth[v])&(1<<e))
			u = lca[e][u];
	if(u == v) return u;
	for(int e = lg-1; e >= 0; e--)
		if(lca[e][u] != lca[e][v])
			u = lca[e][u],
			v = lca[e][v];
	return lca[0][u];
}
int getW(int u, int lc){
	int ans = 0;
	for(int e = lg-1; e >= 0; e--){
		if((depth[u] - depth[lc])&(1<<e)){
			ans = max(ans, w[e][u]);
			u = lca[e][u];
		}
	}
	return ans;
}
int main(){
	int n, m;
	scanf("%d %d", &n, &m);
	vector<pair<int, int> > edges, dsu;
	for(int e = 0; e < m; e++){
		int from, to, cost;
		scanf("%d %d %d", &from, &to, &cost);
		from--; to--;
		edges.push_back({from, to});
		dsu.push_back({cost, e});
	}
	for(int e = 0; e < maxn; e++)
		dad[e] = e;
	sort(dsu.begin(), dsu.end());
	for(int e = 0; e < m; e++){
		int u, v; tie(u, v) = edges[dsu[e].second];
		if(find(u) != find(v)){
			// fprintf(stderr, "(%d, %d)\n", u, v);
			g[u].push_back(v);
			g[v].push_back(u);
			mark[dsu[e].second] = 1;
			dad[find(u)] = find(v);
		}
	}
	for(int e = 0; e < 4*maxn; e++) tree[e] = inf, lazy[e] = 0;
	// fprintf(stderr, "ah\n");
	dfs(0, maxn-1);
	init(0, maxn-1);
	depth[maxn-1] = -1;
	// fprintf(stderr, "%d %d\n", parent[nxt[0]], parent[nxt[4]]);
	// return 0;
	for(int e = 0; e < m; e++){
		int ed, cost; tie(cost, ed) = dsu[e];
		int u, v; tie(u, v) = edges[ed];
		if(mark[ed]){
			if(depth[u] < depth[v]) swap(u, v);
			w[0][u] = cost;
		}
	}
	for(int e = 0; e < n; e++)
		lca[0][e] = parent[e];
	for(int f = 1; f < lg; f++)
		for(int e = 0; e <= n; e++)
			if(lca[f-1][e] != maxn-1){
				lca[f][e] = lca[f-1][lca[f-1][e]];
				w[f][e] = max(w[f-1][e], w[f-1][lca[f-1][e]]);
			}
	// for(int f = 0; f < lg; f++){
	// 	printf("(%d): ", f);
	// 	for(int e = 0; e < n; e++)
	// 		printf("%d%c", w[f][e] , " \n"[e == n-1]);
	// }
	for(int e = 0; e < m; e++){
		int ed, cost; tie(cost, ed) = dsu[e];
		int u, v; tie(u, v) = edges[ed];
		if(!mark[ed]){
			int lc = getLca(u, v);
			ans[ed] = max(getW(u, lc), getW(v, lc)) - 1;
			// printf("(%d, %d)\n", ed, getW(3, 0));
		}
	}
	for(int e = 0; e < 4*maxn; e++) tree[e] = inf, lazy[e] = 0;
	for(int e = 0; e < m; e++){
		int ed, cost; tie(cost, ed) = dsu[e];
		int u, v; tie(u, v) = edges[ed];
		TO = cost;
		if(!mark[ed])
			update(u, v);
	}
	for(int e = 0; e < m; e++){
		int ed, cost; tie(cost, ed) = dsu[e];
		int u, v; tie(u, v) = edges[ed];
		if(mark[ed])
			ans[ed] = query(u, v) - 1;
	}
	for(int e = 0; e < m; e++)
		if(ans[e] == inf - 1)
			ans[e] = -1;
	for(int e = 0; e < m; e++)
		printf("%d ", ans[e]);
	printf("\n");
	return 0;
}


#include "bits/stdc++.h"
using namespace std;
const int maxn = 200200;
const int inf = 1<<30;
int tree[maxn<<2], lazy[maxn<<2];
void push(int id, int l, int r){
	if(lazy[id]){
		tree[id] = min(tree[id], lazy[id]);
		if(l != r){
			lazy[id + id] = min(lazy[id + id], lazy[id]);
			lazy[id + id + 1] = min(lazy[id + id + 1], lazy[id]);
		}
		lazy[id]  = 0;
	}
}
int x, y, TO;
void update(int id, int l, int r){
	push(id, l, r);
	if(r < x || l > y) return;
	if(x <= l && r <= y){
		lazy[id] = TO;
		push(id, l, r);
		return;
	}
	int mid = (l + r) >> 1;
	update(id + id, l, mid);
	update(id + id + 1, mid + 1, r);
	tree[id] = min(tree[id + id], tree[id + id + 1]);
}
int get(int id, int l, int r){
	push(id, l, r);
	if(r < x || l > y) return inf;
	if(x <= l && r <= y) return tree[id];
	int mid = (l + r) >> 1;
	return min(get(id + id, l, mid), get(id + id + 1, mid + 1, r));
}
int nxt[maxn], in[maxn], sz[maxn], T, depth[maxn], parent[maxn];
vector<int> g[maxn];
void dfs(int cur, int p){
	parent[cur] = p;
	sz[cur] = 1;
	for(int &v:g[cur]) if(v != p){
		depth[v] = depth[cur] + 1;
		dfs(v, cur);
		sz[cur] += sz[v];
		if(sz[v] > sz[g[cur][0]] || g[cur][0] == p)
			swap(g[cur][0], v);
	}
}
void init(int cur, int p){
	in[cur] = T++;
	for(int v : g[cur]) if (v != p){
		nxt[v] = (v == g[cur][0])?nxt[cur]:v;
		init(v, cur);
	}
}
void update(int from, int to){
	while(nxt[from] != nxt[to]){
		if(depth[parent[nxt[from]]] < depth[parent[nxt[to]]])
			swap(from, to);
		x = in[nxt[from]]; y = nxt[from];
		update(1, 0, T);
		from = parent[nxt[from]];
	}
	if(in[from] > in[to])
		swap(from, to);
	if(in[from] + 1 <= in[to]){
		x = in[from] + 1; y = in[to];
		update(1, 0, T);
	}
}
int query(int from, int to){
	// fprintf(stderr, "%d -> %d : %d\n", from, to, 0);
	int heavy = inf;
	while(nxt[from] != nxt[to]){
		if(depth[parent[nxt[from]]] < depth[parent[nxt[to]]])
			swap(from, to);
		x = in[nxt[from]]; y = nxt[from];
		heavy = min(heavy, get(1, 0, T) );
		from = parent[nxt[from]];
	}
	// fprintf(stderr, "%d -> %d : %d\n", from, to, 1);
	if(in[from] > in[to])
		swap(from, to);
	if(in[from] + 1 <= in[to]){
		x = in[from] + 1; y = in[to];
		heavy = min(heavy, get(1, 0, T) );
	}
	return heavy;
}
int dad[maxn], mark[maxn], ans[maxn];
int find(int x){
    return (x == dad[x])?x:dad[x] = find(dad[x]);
}
int main(){
	int n, m;
	scanf("%d %d", &n, &m);
	vector<pair<int, int> > edges, dsu;
	for(int e = 0; e < m; e++){
		int from, to, cost;
		scanf("%d %d %d", &from, &to, &cost);
		from--; to--;
		edges.push_back({from, to});
		dsu.push_back({cost, e});
	}
	for(int e = 0; e < maxn; e++)
		dad[e] = e;
	sort(dsu.begin(), dsu.end());
	for(int e = 0; e < m; e++){
		int u, v; tie(u, v) = edges[dsu[e].second];
		if(find(u) != find(v)){
			// fprintf(stderr, "(%d, %d)\n", u, v);
			g[u].push_back(v);
			g[v].push_back(u);
			mark[dsu[e].second] = 1;
			dad[find(u)] = find(v);
		}
	}
	for(int e = 0; e < 4*maxn; e++) tree[e] = inf, lazy[e] = 0;
	// fprintf(stderr, "ah\n");
	dfs(0, -1);
	init(0, -1);
	for(int e = 0; e < m; e++){
		int ed, cost; tie(cost, ed) = dsu[e];
		int u, v; tie(u, v) = edges[ed];
		if(mark[ed]){
			if(depth[u] < depth[v]) swap(u, v);
			x = in[u]; y = in[u]; TO = cost;
			update(1, 0, T);
			// fprintf(stderr, "%d -> %d :: %d = %d\n", u, v, cost, get(1, 0, T));
		}
	}
	for(int e = 0; e < m; e++){
		int ed, cost; tie(cost, ed) = dsu[e];
		int u, v; tie(u, v) = edges[ed];
		if(!mark[ed]){
			ans[ed] = query(u, v) - 1;
			// query(u, v);
			// fprintf(stderr, "%d -> %d : %d\n", u, v, query(u, v));
		}
	}
	for(int e = 0; e < 4*maxn; e++) tree[e] = inf, lazy[e] = 0;
	for(int e = 0; e < m; e++){
		int ed, cost; tie(cost, ed) = dsu[e];
		int u, v; tie(u, v) = edges[ed];
		TO = cost;
		if(!mark[ed])
			update(u, v);
	}
	for(int e = 0; e < m; e++){
		int ed, cost; tie(cost, ed) = dsu[e];
		int u, v; tie(u, v) = edges[ed];
		if(mark[ed])
			ans[ed] = query(u, v) - 1;
	}
	for(int e = 0; e < m; e++)
		if(ans[e] == inf - 1)
			ans[e] = -1;
	for(int e = 0; e < m; e++)
		printf("%d ", ans[e]);
	printf("\n");
	return 0;
}


#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N = 2e5 + 100;
int n,m;
vector< pair<int, int> > g[N];
vector< pair<int, int> > mstTree[N];
int parent[N];
int dist[N];
bool inMST[N];
vector < pair<int, pair<int,int> > > edges;
map< pair<int, int>, int > edge_weight;
long long mst_weight = 0;

long long h[N];
long long dp[N][19];
long long maxi[N][19];

void computeRMQ() {
	for(int i = 1; i <= 18; i++) {
		for(int j = 1; j <= n ; j++) {
			if(dp[j][i-1] != -1) {
				dp[j][i] = dp[dp[j][i-1]][i-1];
				maxi[j][i] = max(maxi[j][i-1], maxi[dp[j][i-1]][i-1]);
			}  else {
				maxi[j][i] = maxi[j][i-1];
			}
		}
	}
}

long long lca(int a, int b) {

	if(h[a] > h[b]) {
		int temp = a;
		a = b;
		b = temp;
	}
	int diff = abs(h[a] - h[b]);
	long long max_weight_edge = 0;

	for(int i = 0; i <= 18; i++) {
		if((diff >> i) & 1) {
			max_weight_edge = max(maxi[b][i], max_weight_edge);
			b = dp[b][i];
		}
	}

	if(b == a)  {
		return max_weight_edge;
	}

	for(int i = 18; i >= 0; i--) {
		if(dp[a][i] != dp[b][i]) {
			max_weight_edge = max(max_weight_edge, maxi[a][i]);
			max_weight_edge = max(max_weight_edge, maxi[b][i]);
			a = dp[a][i];
			b = dp[b][i];
		}
	}
	//cout << "lca is " << dp[a][0] << endl;
	return max(max_weight_edge, max(maxi[a][0], maxi[b][0]));
}

void dfs(int nd, int par) {
	dp[nd][0] = par;
	maxi[nd][0] = edge_weight[make_pair(par, nd)];
	for(auto x: mstTree[nd]) {
		if(x.first != par) {
			h[x.first] = h[nd] + 1;
			dfs(x.first, nd);
		}
	}
}

int find(int nd) {
	while(parent[nd] != nd) {
		nd = parent[nd];
	}
	return nd;
}

vector< pair< int, pair<int, int> > > uselessEdges;
vector< pair< int, pair<int, int> > > mstEdges;

void kruskal() {

	for(int i = 1; i <= n; i++) {
		parent[i] = i;
	}

	int num = n-1;

	for(auto edge: edges) {
		if(num == 0) { uselessEdges.push_back(edge); continue; }
		int d = edge.first;
		int a = edge.second.first;
		int b = edge.second.second;

		int par1 = find(a);
		int par2 = find(b);
		int max_node = a;
		int min_node = a;
		if(par1 >= par2) {
			max_node = a;
			min_node = b;
		} else {
			max_node = b;
			min_node = a;
		}

		if(par1 != par2) {
		//	cout << "cycle doesn't exist between " << a << " " << b << endl;
			int maxi = max(par1, par2);
			parent[maxi] = min(par1, par2);
			mstEdges.push_back(edge);
			mstTree[a].push_back(make_pair(b, d));
			mstTree[b].push_back(make_pair(a, d));
			edge_weight[make_pair(a, b)] = edge_weight[make_pair(b, a)] = d;
			mst_weight += d;
			parent[max_node] = min_node;
			num -= 1;
		} else {
		//	cout << "cycle exist between " << a << " " << b << endl;
			uselessEdges.push_back(edge);
		}

	}

}

map< pair<int, int>, int> ans;

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> n >> m;
	for(int i = 0; i < m; i++) {
		int a, b, c;
		cin >> a >> b >> c;
		g[a].push_back(make_pair(b, c));
		g[b].push_back(make_pair(a, c));
		edges.push_back(make_pair(c, make_pair(a, b)));
	}

	sort(edges.begin(), edges.end());
	kruskal();

	//cout << mst_weight << " " << endl;

	sort(uselessEdges.begin(), uselessEdges.end());
	edge_weight[make_pair(0, 1)] = 0;
	h[1] = 0;
	dfs(1, 0);
	computeRMQ();

	for(auto edge: mstEdges) {
		int d = edge.first;
		int a = edge.second.first;
		int b = edge.second.second;

	//	cout << "processing mst edge " << a << " " << b << endl;

		if(h[a] <= h[b]) {
			int temp = parent[b];
			parent[b] = b;
			bool ans_found = false;
			for(auto useless: uselessEdges) {
				int d1 = useless.first;
				int a1 = useless.second.first;
				int b1 = useless.second.second;

				int par1 = find(a1);
				int par2 = find(b1);

				if(par1 != par2) {
	//				cout << "cross edge found between " << a1 << " " << b1 << endl;
	//				cout << "answer is " << d1 - 1 << endl;
					ans[make_pair(a, b)] = ans[make_pair(b, a)] = d1 - 1;
					ans_found = true;
					break;
				}
			}

				if(!ans_found) ans[make_pair(a,b)] = ans[make_pair(b,a)] = -1;
				parent[b] = temp;
			} else {
			int temp = parent[a];
			parent[a] = a;
			bool ans_found = false;

			for(auto useless: uselessEdges) {
				int d1 = useless.first;
				int a1 = useless.second.first;
				int b1 = useless.second.second;

				int par1 = find(a1);
				int par2 = find(b1);

				if(par1 != par2) {
	//				cout << "cross edge found between " << a1 << " " << b1 << endl;
					ans[make_pair(a, b)] = ans[make_pair(b, a)] = d1 - 1;
					ans_found = true;
	//				cout << "answer is " << d1 - 1 << endl;
					break;
				}
			}
				parent[a] = temp;
				if(!ans_found) ans[make_pair(a,b)] = ans[make_pair(b,a)] = -1;

		}

	}

	for(auto edge: edges) {
		int a = edge.second.first;
		int b = edge.second.second;
		if(parent[a] == b or parent[b] == a) {
			cout << ans[make_pair(a, b)] << endl;
			continue;
		}

	//	cout << "finding useless edge ans" << endl;
		int maxi = lca(a, b);
		cout << maxi - 1 << endl;

	}

	return 0;
}


#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N = 2e5 + 100;
int n,m;
vector< pair<int, int> > g[N];
vector< pair<int, int> > mstTree[N];

//root for dsu,
int parent[N];

//parent in mst
int mst_parent[N];

int dist[N];
bool inMST[N];
vector < pair<int, pair<int,int> > > edges, original_order;
map< pair<int, int>, int > edge_weight;
long long mst_weight = 0;

long long h[N];
long long dp[N][19];
long long maxi[N][19];

void computeRMQ() {
	for(int i = 1; i <= 18; i++) {
		for(int j = 1; j <= n ; j++) {
			if(dp[j][i-1] != -1) {
				dp[j][i] = dp[dp[j][i-1]][i-1];
				maxi[j][i] = max(maxi[j][i-1], maxi[dp[j][i-1]][i-1]);
			}  else {
				maxi[j][i] = maxi[j][i-1];
			}
		}
	}
}

long long lca(int a, int b) {

	if(h[a] > h[b]) {
		int temp = a;
		a = b;
		b = temp;
	}
	int diff = abs(h[a] - h[b]);
	long long max_weight_edge = 0;

	for(int i = 0; i <= 18; i++) {
		if((diff >> i) & 1) {
			max_weight_edge = max(maxi[b][i], max_weight_edge);
			b = dp[b][i];
		}
	}

	if(b == a)  {
		return max_weight_edge;
	}

	for(int i = 18; i >= 0; i--) {
		if(dp[a][i] != dp[b][i]) {
			max_weight_edge = max(max_weight_edge, maxi[a][i]);
			max_weight_edge = max(max_weight_edge, maxi[b][i]);
			a = dp[a][i];
			b = dp[b][i];
		}
	}

	return max(max_weight_edge, max(maxi[a][0], maxi[b][0]));
}

void dfs(int nd, int par) {
	dp[nd][0] = par;
	maxi[nd][0] = edge_weight[make_pair(par, nd)];
	mst_parent[nd] = par;
	for(auto x: mstTree[nd]) {
		if(x.first != par) {
			h[x.first] = h[nd] + 1;
			dfs(x.first, nd);
		}
	}
}

int find(int nd) {
	while(parent[nd] != nd) {
		nd = parent[nd];
	}
	return nd;
}

int find1(int nd) {
	while(mst_parent[nd] != nd) {
		nd = mst_parent[nd];
	}
	return nd;
}

vector< pair< int, pair<int, int> > > uselessEdges;
vector< pair< int, pair<int, int> > > mstEdges;

void kruskal() {

	for(int i = 1; i <= n; i++) {
		parent[i] = i;
	}

	int num = n-1;

	for(auto edge: edges) {
		if(num == 0) {
			uselessEdges.push_back(edge);
			continue;

		}
		int d = edge.first;
		int a = edge.second.first;
		int b = edge.second.second;

		int par1 = find(a);
		int par2 = find(b);
		int max_node = a;
		int min_node = a;
		if(par1 >= par2) {
			max_node = a;
			min_node = b;
		} else {
			max_node = b;
			min_node = a;
		}

		if(par1 != par2) {
			int maxi = max(par1, par2);
			parent[maxi] = min(par1, par2);
			mstEdges.push_back(edge);
			mstTree[a].push_back(make_pair(b, d));
			mstTree[b].push_back(make_pair(a, d));
			edge_weight[make_pair(a, b)] = edge_weight[make_pair(b, a)] = d;
			mst_weight += d;
			num -= 1;
		} else {
			uselessEdges.push_back(edge);
		}

	}

}

map< pair<int, int>, int> ans;

bool cmp(pair<int, pair<int, int> > a, pair<int, pair<int, int> > b) {
	return a.first >= b.first;
}

signed main() {
	scanf("%lld %lld", &n, &m);
	for(int i = 0; i < m; i++) {
		int a, b, c;
		scanf("%lld %lld %lld", &a, &b, &c);
		g[a].push_back(make_pair(b, c));
		g[b].push_back(make_pair(a, c));
		edges.push_back(make_pair(c, make_pair(a, b)));
		original_order.push_back(edges.back());
	}

	sort(edges.begin(), edges.end());
	kruskal();
	sort(uselessEdges.begin(), uselessEdges.end());
	edge_weight[make_pair(0, 1)] = 0;
	h[1] = 0;
	mst_parent[1] = 0;
	dfs(1, 0);
	computeRMQ();

	for(auto edge: mstEdges) {
		int d = edge.first;
		int a = edge.second.first;
		int b = edge.second.second;

		if(h[a] <= h[b]) {
			int temp = mst_parent[b];
			mst_parent[b] = b;
			bool ans_found = false;
			for(auto useless: uselessEdges) {
				int d1 = useless.first;
				int a1 = useless.second.first;
				int b1 = useless.second.second;

				int par1 = find1(a1);
				int par2 = find1(b1);

				if(par1 != par2) {
					ans[make_pair(a, b)] = ans[make_pair(b, a)] = d1 - 1;
					ans_found = true;
					break;
				}
			}

				if(!ans_found) ans[make_pair(a,b)] = ans[make_pair(b,a)] = -1;
				mst_parent[b] = temp;
			} else {
			int temp = mst_parent[a];
			mst_parent[a] = a;
			bool ans_found = false;

			for(auto useless: uselessEdges) {
				int d1 = useless.first;
				int a1 = useless.second.first;
				int b1 = useless.second.second;

				int par1 = find1(a1);
				int par2 = find1(b1);

				if(par1 != par2) {
					ans[make_pair(a, b)] = ans[make_pair(b, a)] = d1 - 1;
					ans_found = true;
					break;
				}
			}
				mst_parent[a] = temp;
				if(!ans_found) ans[make_pair(a,b)] = ans[make_pair(b,a)] = -1;

		}

	}

	for(auto edge: original_order) {
		int a = edge.second.first;
		int b = edge.second.second;
		if(mst_parent[a] == b or mst_parent[b] == a) {
			cout << ans[make_pair(a, b)] << endl;
			continue;
		}

		int maxi = lca(a, b);
		cout << maxi - 1 << endl;

	}

	return 0;
}


#include <bits/stdc++.h>
#define int long long
#define inf 1e9 + 7
using namespace std;

const int N = 2e5 + 100;
int n,m;
vector< pair<int, int> > g[N];
vector< pair<int, int> > mstTree[N];

//root for dsu,
int parent[N];

//parent in mst
int mst_parent[N];

int dist[N];
bool inMST[N];
vector < pair<int, pair<int,int> > > edges, original_order;
map< pair<int, int>, int > edge_weight;
long long mst_weight = 0;

long long h[N];
long long dp[N][19];
long long maxi[N][19];
long long mini[N][19];

map< pair<int, int>, int> ans;

void computeRMQ() {
	for(int i = 1; i <= 18; i++) {
		for(int j = 1; j <= n ; j++) {
			if(dp[j][i-1] != -1) {
				dp[j][i] = dp[dp[j][i-1]][i-1];
				maxi[j][i] = max(maxi[j][i-1], maxi[dp[j][i-1]][i-1]);
			}  else {
				maxi[j][i] = maxi[j][i-1];
			}
			mini[j][i] = inf;
			mini[j][0] = inf;
		}
	}
}

pair<int, int>  lca(int a, int b) {

	if(h[a] > h[b]) {
		int temp = a;
		a = b;
		b = temp;
	}
	int diff = abs(h[a] - h[b]);
	long long max_weight_edge = 0;

	for(int i = 0; i <= 18; i++) {
		if((diff >> i) & 1) {
			max_weight_edge = max(maxi[b][i], max_weight_edge);
			b = dp[b][i];
		}
	}

	if(b == a)  {
		return make_pair(a, max_weight_edge);
	}

	for(int i = 18; i >= 0; i--) {
		if(dp[a][i] != dp[b][i]) {
			max_weight_edge = max(max_weight_edge, maxi[a][i]);
			max_weight_edge = max(max_weight_edge, maxi[b][i]);
			a = dp[a][i];
			b = dp[b][i];
		}
	}

	return make_pair(dp[a][0], max(max_weight_edge, max(maxi[a][0], maxi[b][0])));
}

void dfs(int nd, int par) {
	dp[nd][0] = par;
	maxi[nd][0] = edge_weight[make_pair(par, nd)];
	mst_parent[nd] = par;
	for(auto x: mstTree[nd]) {
		if(x.first != par) {
			h[x.first] = h[nd] + 1;
			dfs(x.first, nd);
		}
	}
}

void dfs2(int nd, int par) {
	for(auto x: mstTree[nd]) {
		ans[make_pair(nd, par)] = mini[x.first][0];
		ans[make_pair(par, nd)] = mini[x.first][0];
		if(x.first != par) {
			dfs2(x.first, nd);
		}
	}
}

int find(int nd) {
	while(parent[nd] != nd) {
		nd = parent[nd];
	}
	return nd;
}

vector< pair< int, pair<int, int> > > uselessEdges;
vector< pair< int, pair<int, int> > > mstEdges;

void update(int nd, int lca, int val) {
	int diff = abs(h[lca] - h[nd]);
	for(int i = 18; i >= 0; i--) {
		if( diff  & (1 << i)) {
			mini[nd][i] = min(mini[nd][i], val);
			nd = dp[nd][i];
		}
	}
}

void kruskal() {

	for(int i = 1; i <= n; i++) {
		parent[i] = i;
	}

	int num = n-1;

	for(auto edge: edges) {
		if(num == 0) {
			uselessEdges.push_back(edge);
			continue;

		}
		int d = edge.first;
		int a = edge.second.first;
		int b = edge.second.second;

		int par1 = find(a);
		int par2 = find(b);
		int max_node = a;
		int min_node = a;
		if(par1 >= par2) {
			max_node = a;
			min_node = b;
		} else {
			max_node = b;
			min_node = a;
		}

		if(par1 != par2) {
			int maxi = max(par1, par2);
			parent[maxi] = min(par1, par2);
			mstTree[a].push_back(make_pair(b, d));
			mstTree[b].push_back(make_pair(a, d));
			edge_weight[make_pair(a, b)] = edge_weight[make_pair(b, a)] = d;
			mst_weight += d;
			num -= 1;
		} else {
			uselessEdges.push_back(edge);
		}

	}

}

signed main() {
	scanf("%lld %lld", &n, &m);
	for(int i = 0; i < m; i++) {
		int a, b, c;
		scanf("%lld %lld %lld", &a, &b, &c);
		g[a].push_back(make_pair(b, c));
		g[b].push_back(make_pair(a, c));
		edges.push_back(make_pair(c, make_pair(a, b)));
		original_order.push_back(edges.back());
	}

	sort(edges.begin(), edges.end());
	kruskal();
	sort(uselessEdges.begin(), uselessEdges.end());
	edge_weight[make_pair(0, 1)] = 0;
	h[1] = 0;
	mst_parent[1] = 0;
	dfs(1, 0);
	computeRMQ();

	for(auto useless: uselessEdges) {
		int a = useless.second.first;
		int b = useless.second.second;
		int d = useless.first;
		pair<int, int> answer = lca(a, b);
		ans[make_pair(a, b)] = answer.second;
		ans[make_pair(b, a)] = answer.second;
		update(a, answer.first, d);
		update(b, answer.first, d);
	}

	for(int l = 18; l >= 1; l--) {
		for(int nd = 1; nd <= n; nd++) {
			mini[nd][l-1] = min(mini[nd][l-1], mini[nd][l]);
			mini[dp[nd][l-1]][l-1] = min(mini[nd][l], mini[dp[nd][l-1]][l-1]);
		}
	}

	dfs2(1, 0);
	for(auto edge: original_order) {
		int a = edge.second.first;
		int b = edge.second.second;
		if(mst_parent[a] == b or mst_parent[b] == a) {
			if(ans[make_pair(a, b)] == inf or ans[make_pair(b,a)] == inf )
				cout << -1 << endl;
			else
				cout << ans[make_pair(a, b)] - 1 << endl;
			continue;
		}

		pair<int, int> ans = lca(a, b);
		cout << ans.second - 1  << endl;

	}

	return 0;
}


#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N = 2e5 + 100;
int n,m;
vector< pair<int, int> > g[N];
vector< pair<int, int> > mstTree[N];

//root for dsu,
int parent[N];

//parent in mst
int mst_parent[N];

int dist[N];
bool inMST[N];
vector < pair<int, pair<int,int> > > edges, original_order;
map< pair<int, int>, int > edge_weight;
long long mst_weight = 0;

long long h[N];
long long dp[N][19];
long long maxi[N][19];

void computeRMQ() {
	for(int i = 1; i <= 18; i++) {
		for(int j = 1; j <= n ; j++) {
			if(dp[j][i-1] != -1) {
				dp[j][i] = dp[dp[j][i-1]][i-1];
				maxi[j][i] = max(maxi[j][i-1], maxi[dp[j][i-1]][i-1]);
			}  else {
				maxi[j][i] = maxi[j][i-1];
			}
		}
	}
}

long long lca(int a, int b) {

	if(h[a] > h[b]) {
		int temp = a;
		a = b;
		b = temp;
	}
	int diff = abs(h[a] - h[b]);
	long long max_weight_edge = 0;

	for(int i = 0; i <= 18; i++) {
		if((diff >> i) & 1) {
			max_weight_edge = max(maxi[b][i], max_weight_edge);
			b = dp[b][i];
		}
	}

	if(b == a)  {
		return max_weight_edge;
	}

	for(int i = 18; i >= 0; i--) {
		if(dp[a][i] != dp[b][i]) {
			max_weight_edge = max(max_weight_edge, maxi[a][i]);
			max_weight_edge = max(max_weight_edge, maxi[b][i]);
			a = dp[a][i];
			b = dp[b][i];
		}
	}

	return max(max_weight_edge, max(maxi[a][0], maxi[b][0]));
}

void dfs(int nd, int par) {
	dp[nd][0] = par;
	maxi[nd][0] = edge_weight[make_pair(par, nd)];
	mst_parent[nd] = par;
	for(auto x: mstTree[nd]) {
		if(x.first != par) {
			h[x.first] = h[nd] + 1;
			dfs(x.first, nd);
		}
	}
}

int find(int nd) {
	while(parent[nd] != nd) {
		nd = parent[nd];
	}
	return nd;
}

int find1(int nd) {
	while(mst_parent[nd] != nd) {
		nd = mst_parent[nd];
	}
	return nd;
}

vector< pair< int, pair<int, int> > > uselessEdges;
vector< pair< int, pair<int, int> > > mstEdges;

void kruskal() {

	for(int i = 1; i <= n; i++) {
		parent[i] = i;
	}

	int num = n-1;

	for(auto edge: edges) {
		if(num == 0) {
			uselessEdges.push_back(edge);
			continue;

		}
		int d = edge.first;
		int a = edge.second.first;
		int b = edge.second.second;

		int par1 = find(a);
		int par2 = find(b);
		int max_node = a;
		int min_node = a;
		if(par1 >= par2) {
			max_node = a;
			min_node = b;
		} else {
			max_node = b;
			min_node = a;
		}

		if(par1 != par2) {
			int maxi = max(par1, par2);
			parent[maxi] = min(par1, par2);
			mstEdges.push_back(edge);
			mstTree[a].push_back(make_pair(b, d));
			mstTree[b].push_back(make_pair(a, d));
			edge_weight[make_pair(a, b)] = edge_weight[make_pair(b, a)] = d;
			mst_weight += d;
			num -= 1;
		} else {
			uselessEdges.push_back(edge);
		}

	}

}

map< pair<int, int>, int> ans;

bool cmp(pair<int, pair<int, int> > a, pair<int, pair<int, int> > b) {
	return a.first >= b.first;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> n >> m;
	for(int i = 0; i < m; i++) {
		int a, b, c;
		cin >> a >> b >> c;
		g[a].push_back(make_pair(b, c));
		g[b].push_back(make_pair(a, c));
		edges.push_back(make_pair(c, make_pair(a, b)));
		original_order.push_back(edges.back());
	}

	sort(edges.begin(), edges.end());
	kruskal();
	sort(uselessEdges.begin(), uselessEdges.end());
	edge_weight[make_pair(0, 1)] = 0;
	h[1] = 0;
	mst_parent[1] = 0;
	dfs(1, 0);
	computeRMQ();

	for(auto edge: mstEdges) {
		int d = edge.first;
		int a = edge.second.first;
		int b = edge.second.second;

		if(h[a] <= h[b]) {
			int temp = mst_parent[b];
			mst_parent[b] = b;
			bool ans_found = false;
			for(auto useless: uselessEdges) {
				int d1 = useless.first;
				int a1 = useless.second.first;
				int b1 = useless.second.second;

				int par1 = find1(a1);
				int par2 = find1(b1);

				if(par1 != par2) {
					ans[make_pair(a, b)] = ans[make_pair(b, a)] = d1 - 1;
					ans_found = true;
					break;
				}
			}

				if(!ans_found) ans[make_pair(a,b)] = ans[make_pair(b,a)] = -1;
				mst_parent[b] = temp;
			} else {
			int temp = mst_parent[a];
			mst_parent[a] = a;
			bool ans_found = false;

			for(auto useless: uselessEdges) {
				int d1 = useless.first;
				int a1 = useless.second.first;
				int b1 = useless.second.second;

				int par1 = find1(a1);
				int par2 = find1(b1);

				if(par1 != par2) {
					ans[make_pair(a, b)] = ans[make_pair(b, a)] = d1 - 1;
					ans_found = true;
					break;
				}
			}
				mst_parent[a] = temp;
				if(!ans_found) ans[make_pair(a,b)] = ans[make_pair(b,a)] = -1;

		}

	}

	for(auto edge: original_order) {
		int a = edge.second.first;
		int b = edge.second.second;
		if(mst_parent[a] == b or mst_parent[b] == a) {
			cout << ans[make_pair(a, b)] << endl;
			continue;
		}

		int maxi = lca(a, b);
		cout << maxi - 1 << endl;

	}

	return 0;
}