public static int Boruvka(Graph input) {
		input.setState(States.ARR_ADJ);
		Log.print(Log.system, "Boruvka algorithm:");

		// init:
		int N = input.getVertexCount();
		int M = input.getEdgeCount();
		int[][] arr_inc = new int[N][M];
		int[][] arr_adj = new int[N][N];
		@SuppressWarnings("unchecked")
		ArrayList<ListNode>[] list_adj = new ArrayList[N];

		// init data:
		for (int i = 0; i < N; i++) {
			Arrays.fill(arr_adj[i], 0);
			Arrays.fill(arr_inc[i], 0);
			list_adj[i] = new ArrayList<ListNode>();
		}

		// Boruvka init:
		ArrayList<Edge> edges = input.getEdges();
		ArrayList<Edge> resultEdges = new ArrayList<>();
		DSF dsf = new DSF(input.getVertexCount());
		Edge[] min = new Edge[input.getVertexCount()];

		while (resultEdges.size() < input.getVertexCount() - 1) {
			Arrays.fill(min, new Edge(0, 0, 9_999_999));
			for (Edge e : edges) {
				if (dsf.set(e.u) != dsf.set((e.v))) {
					if (e.w < min[e.u].w)
						min[e.u] = e;
				}
			}
			for (int i = 0; i < input.getVertexCount(); i++) {
				if (min[i].w != 9_999_999) {
					if (dsf.set(min[i].u) != dsf.set((min[i].v))) {
						resultEdges.add(min[i]);
						System.out.println("Boruvka: edge " + (min[i].u + 1)
								+ " " + (min[i].v + 1));
					}
					dsf.union(min[i].u, min[i].v);
				}
			}
		}
		return 0;
	}