// Arup Guha
// Started a while back.
// Finished on 6/24/2024
// Solution to 2023 NAC Problem C: Broken Minimum Spanning Tree

import java.util.*;

public class c {

	public static int n;
	public static int m;
	public static edge[] list;
	public static edge[] sorted;
	
	public static void main(String[] args) {
	
		Scanner stdin = new Scanner(System.in);
		n = stdin.nextInt();
		m = stdin.nextInt();
		list = new edge[m];
		sorted = new edge[m];
		
		for (int i=0; i<m; i++) {
			int u = stdin.nextInt()-1;
			int v = stdin.nextInt()-1;
			int w = stdin.nextInt();
			list[i] = new edge(u,v,w,i);
			sorted[i] = list[i];
		}
		
		// Get mst.
		Arrays.sort(sorted);
		edge[] mst = kruskals();
		
		// Calculate # of swaps.
		int numSwaps = 0;
		for (int i=0; i<n-1; i++)
			if (mst[i].id >= n-1)
				numSwaps++;
			
		// Store Ethan's spanning tree.
		ArrayList<edge>[] g = new ArrayList[n];
		for (int i=0; i<n; i++)
			g[i] = new ArrayList<edge>();
		for (int i=0; i<n-1; i++) {
			g[list[i].u].add(new edge(list[i].u, list[i].v, list[i].w, list[i].id));
			g[list[i].v].add(new edge(list[i].v, list[i].u, list[i].w, list[i].id));
		}
		
		// The number of swaps we need.
		System.out.println(numSwaps);
		for (int i=0; i<n-1; i++) {
			
			// This edge doesn't need to be replaced.
			if (mst[i].id < n-1) continue;
			
			// Find edge we're removing.
			int remid = bfs(g, mst[i].u, mst[i].v) ;
			
			// Print the output.
			System.out.println( (remid+1)+" "+(mst[i].id+1));
			
			// Add this edge.
			g[mst[i].u].add(new edge(mst[i].u, mst[i].v, mst[i].w, mst[i].id));
			g[mst[i].v].add(new edge(mst[i].v, mst[i].u, mst[i].w, mst[i].id));
			
			// Find the edge to remove.
			edge rem1 = null, rem2 = null;
			for (edge x: g[list[remid].u])
				if (x.id == remid)
					rem1 = x;
				
			// Remove it.
			g[list[remid].u].remove(rem1);
			
			// Repeat this for other vertex.
			for (edge x: g[list[remid].v])
				if (x.id == remid)
					rem2 = x;
				
			// Remove it!
			g[list[remid].v].remove(rem2);
		}
	}
	
	// Returns the id of the maximum edge weight on the path from myu to myv in g.
	public static int bfs(ArrayList<edge>[] g, int myu, int myv) {
		
		// Set up BFS.
		int[] maxEdgeID = new int[n];
		Arrays.fill(maxEdgeID, -1);
		ArrayDeque<Integer> q = new ArrayDeque<Integer>();
		q.offer(myu);
		maxEdgeID[myu] = g[myu].get(0).id;
		
		// We can stop when we get to myv.
		while (maxEdgeID[myv] == -1) {
			
			// Get next vertex.
			int cur = q.poll();
			
			// Look at edges.
			for (edge x: g[cur]) {
				
				if (maxEdgeID[x.v] != -1) continue;
				
				// Special case, first edge, it's the max so far.
				if (cur == myu)
					maxEdgeID[x.v] = x.id;
				
				// Here we take the larger of the old largest edge and this edge x.
				else {
					maxEdgeID[x.v] = maxEdgeID[cur];
					int oldw = list[maxEdgeID[cur]].w;
					int neww = x.w;
					if (neww > oldw || (neww==oldw && x.id > list[maxEdgeID[cur]].id) )
						maxEdgeID[x.v] = x.id;		
				}
				
				// Add this vertex to the queue.
				q.offer(x.v);
			}
			
		}
		
		// Ta da!
		return maxEdgeID[myv];
	}
	
	// Returns mst.
	public static edge[] kruskals() {
		
		edge[] res = new edge[n-1];
		djset dj = new djset(n);
		int numE = 0;
		
		// Go through edges in order.
		for (int i=0; numE<n-1; i++) {
			
			// See if these two are connected yet.
			boolean ok = dj.union(sorted[i].u, sorted[i].v);
			if (!ok) continue;
			
			// Add this one in.
			res[numE++] = sorted[i];
		}
		
		return res;
	}
}

// Disjoint Set Class
class djset {
	
	public int[] par;
	
	public djset(int n) {
		par = new int[n];
		for (int i=0; i<n; i++)
			par[i] = i;
	}
	
	public int find(int u) {
		if (par[u] == u) return u;
		return par[u] = find(par[u]);
	}
	
	public boolean union(int u, int v) {
		u = find(u);
		v = find(v);
		if (u == v) return false;
		par[v] = u;
		return true;
	}
}

// Edge class for mst.
class edge implements Comparable<edge> {

	public int u;
	public int v;
	public int w;
	public int id;
	
	public edge(int myu, int myv, int myw, int mid) {
		u = myu;
		v = myv;
		w = myw;
		id = mid;
	}
	
	public int compareTo(edge other) {
		if (w != other.w) return w - other.w;
		return id - other.id;
	}
}