void mstConstruction() {  
	CStopWatch tstopwatch;
	tstopwatch.start();

	uint32_t rid, prid, aroot, broot;
	size_t edgesidx = 0;

	int maxL = max(L1, L2);
	char *stra = (char*)alloca((maxL + 1) * sizeof(char));
	char *encstr = (char*)alloca(((maxL<<2) + 1) * sizeof(char));

	rootarr = new uint32_t[max_rid];

	for (uint32_t i = 0; i < max_rid; ++i) {
		rootarr[i] = i;
	}
	cout << "begin mstConstruction() ..." << endl;

	MstEdge_v mstedges;
	kv_init(mstedges);

	// process dif == 0;
	while (edgesidx < edges.n && edges.a[edgesidx].dif == 0) {
		rid = edges.a[edgesidx].rid;
		prid = edges.a[edgesidx].prid;
		if (getRoot(rid) != getRoot(prid)) { //these two reads not in a tree
			aroot = getRoot(rid);
			broot = getRoot(prid);
			rootarr[aroot] = broot;

			MstEdge_t teds(rid, prid, 0, edges.a[edgesidx].isrc);
			kv_push(MstEdge_t, mstedges, teds);

			duplicateEdges.push_back(make_pair(rid, prid));
		}
		++ edgesidx;
	}
	kv_destroy(edges);

	for (int dif = 1; dif <= max_dif_thr; ++ dif) {
		// if (false) // for debug
		// for shift edges
		for (int threadid = 0; threadid < nthreads; ++threadid) {
			shiftEdgesFile_t *edf = &threadshifteds[threadid].a[dif - 1];
			// edf->reopen(maxedges);
			edf->reopen();

			while (edf->get()) {
			// bool getres;
			// while (getres = edf->get()) {
				// cout << "edf->fn: " << edf->fn << endl;
				// cout << "getres: " << getres << endl;
				// cout << "edf->n: " << edf->n << endl;
				// cout << "edf->m: " << edf->m << endl;

				for (uint32_t i = 0; i < edf->n; ++i) {
					uint64_t v = edf->a[i];
					rid = v >> 32;
					prid = (uint32_t) v;
					int16_t shiftisrc = edf->shift[i];

					if (getRoot(rid) != getRoot(prid)) { //these two reads not in a tree
						MstEdge_t teds(rid, prid, shiftisrc >> 1, shiftisrc & 1);
						kv_push(MstEdge_t, mstedges, teds);
						//
						aroot = getRoot(rid);
						broot = getRoot(prid);
						rootarr[aroot] = broot;
					}
				}
			}
			// cout << "before clear\n";
			edf->clear();
		}
	}
	cout << endl;
	for (int threadid = 0; threadid < nthreads; ++threadid) {
		threadshifteds[threadid].removefd();
		// threadeds[threadid].removefd();
	}
	// edgfolder = folder + "edges";
	// string cmd = "rm -rf " + folder + "edges " + folder + "shiftedges " + folder + "shiftedgesbysubstridx";
	// string cmd = "rm -rf " + hammingedgfolder + " " + shiftedgfolder ;
	string cmd = "rm -rf " + shiftedgfolder ;
	system(cmd.c_str());

	cout << "Time of edges of mstConstruction() = " << tstopwatch.stop() << std::endl;
	tstopwatch.resume();

	// radix_sort_mstedge(mstedges.a, mstedges.a + mstedges.n);

	bool *v = new bool[max_rid], isrc;
	memset(v, false, sizeof(bool) * max_rid);
	int16_t shift;
	// FILE *fp = fopen("1.txt", "w");
	cout << "Number of edges in MST: " << mstedges.n << endl;
	for (size_t i = 0; i < mstedges.n; ++i) {
		rid = mstedges.a[i].rid;
		prid = mstedges.a[i].prid;
		isrc = mstedges.a[i].isrc;
		shift = mstedges.a[i].shift;
		// fprintf(fp, "%u %u\n", prid, rid);

		if (v[rid] && !v[prid]) {
			rid = prid;
			prid = mstedges.a[i].rid;
			if (!isrc) {
				shift = 0 - shift; 
			}
		} 
		else 
		if (v[rid] && v[prid]) {
			// cout << "prid: " << prid << "; " << "rid: " << rid << endl;
			reRootNode(rid);
		}
		reads[rid].prid = prid;
		reads[rid].shift = shift;
		reads[rid].isrc = isrc;
		kv_push(uint32_t, reads[prid].crid, rid);
		v[rid] = v[prid] = true;
	}
	delete[] v;
	delete[] rootarr;
	cout << "Time of mstConstruction() = " << tstopwatch.stop() << std::endl;
	// fclose(fp);

	removeDuplicateEdges();

	cout << "end mstConstruction() ...\n";
}