class LazyPrimMST:
    def __init__(self, ewg):
        #ewg is an edge weighted graph
        self.pq = MinPQ()
        self.marked = [False] * (ewg.v + 1)
        self.mst = Queue()

        self._visit(ewg, 0)

        while not self.pq.isEmpty():
            e = self.pq.dequeue()
            v = e.either()
            w = e.other(v)
            if (self.marked[v] == True and self.marked[w] == True):
                continue
            self.mst.enqueue(e)
            if not self.marked[v] == True:
                self._visit(ewg, v)
            if not self.marked[w] == True:
                self._visit(ewg, w)

    def _visit(self, ewg, v):
        self.marked[v] = True
        for e in ewg.adj(v):
            if not self.marked[e.other(v)] == True:
                self.pq.enqueue(e)

    def edges(self):
        return self.mst
class LazyPrimMST:

	def __init__(self,ewg):
		#ewg is an edge weighted graph
		self.pq = MinPQ()
		self.marked = [False] * (ewg.v+1)
		self.mst = Queue()

		self._visit(ewg,0)

		while not self.pq.isEmpty():
			e = self.pq.dequeue()
			v = e.either()
			w = e.other(v)
			if (self.marked[v] == True and self.marked[w] == True):
				continue 
			self.mst.enqueue(e)
			if not self.marked[v] == True:
				self._visit(ewg,v)
			if not self.marked[w] == True :
				self._visit(ewg,w)



	def _visit(self,ewg,v):
		self.marked[v] = True
		for e in ewg.adj(v):
			if not self.marked[e.other(v)] == True :
				self.pq.enqueue(e)

	def edges(self):
		return self.mst
class KruskalMST:
	def __init__(self,ewg):
		self._mst = Queue()
		self._pq = MinPQ(ewg.edges())
		self._uf = UnionFind(ewg.v+1)

		while not self._pq.isEmpty() and self._mst.size < ewg.v-1:
			#get minimum weighted ege on the PQ
			e = self._pq.dequeue()
			#get the first vertex
			v = e.either()
			#get the second 
			w = e.other(v)

			if (self._uf.connected(v,w)):
				continue 
			self._uf.union(v,w)
			self._mst.enqueue(e)

	def edges(self):
		return self._mst