It's Galactik Football time! The Galactik Football Assosiation (GFA) has announced a football tournament between all the teams of all the planets in the galaxy.

Each planet of the galaxy has a government. Some governments have a mutual agreement between them. If planet $A$ has mutual agreement with planet $B$, then there is a bidirectional spaceway between $A$ and $B$, using which anybody can go from $A$ to $B$ and vice-versa. People can use these spaceways to travel from one planet to another, if there exists a path between them using some of the spaceways.

Each planet has its own football ground. The GFA has planned the matches in such a way that a team can have a match at any of these grounds. The GFA has come across some problems in the execution of their plan. They have found out that there are many pairs of planets between which there does not exist any path, so the football team of one of those planets can't reach the other planet. They requested the corresponding governments to make a spaceway between them, but they can’t because of the absence of a mutual agreement. So the GFA suggested that they will make teleportation devices between some pairs of planets which will be used only by the football teams to travel.

But there are two types of governments in the galaxy
1. Some of the governments are greedy and they want to make money through the GFA. Each of these government has asked the GFA for a tax value which it has to pay if it wants to make a teleport ending at their planet.
2. Others want to sponsor the event, so they will give money to the GFA if they make a teleport ending at their planet. The GFA would always avoid such governments no matter what the consequences are, because these kind of governments always have some dirty plans up their sleeves.

Now, the GFA wants to make bi-directional teleports between planets such that the football teams of any planet can reach any other planet to play a football match, using spaceways between the planets and/or teleports made by the GFA.

The GFA also has financial problems and want to spend as little money as possible. They have come to you so that you can help them calculate the minimum amount of money needed to fulfil their plan.

------  Input ------
The first line of the input consists of two space separated integers - $N$ and $M$. $N$ is the number of planets and $M$ is the number of spaceways. The description of the spaceways follows. 
The next $M$ lines, each contain two space separated integers $A$ and $B$, denoting a mutual agreement and hence a spaceway to travel, between planet $A$ and planet $B$.
The next $N$ lines each contain a single integer, the integer on the $i^{th}$ line representing $C_{i}$. If $C_{i} ≥ 0$, then it represents the tax value which the GFA has to pay to the government of planet $i$ (it's a type $1$ government). If $C_{i} < 0$, then it represents the money that the $i^{th}$ government will pay to the GFA (it's a type $2$ government).

------  Output ------
Print the minimum amount needed for the GFA to fulfil their plan. If there is no way to do so, print "-1" (without quotes).

------  Constraints ------
$1 ≤ N ≤ 10^{5}$
$0 ≤ M ≤ 10^{6}$
$0 ≤ |C| ≤ 10^{4}$
$1 ≤ A,B ≤ N$
$A \neq B$

----- Sample Input 1 ------ 
6 6
1 2
2 3
1 3
4 5
5 6
4 6
1
3
5
2
4
6
----- Sample Output 1 ------ 
3
----- explanation 1 ------ 

----- Sample Input 2 ------ 
3 1
2 3
1
-1
-1
----- Sample Output 2 ------ 
-1
----- explanation 2 ------

Difficulty: MEDIUM_HARD

Solutions:
class DisjointSet:

	def __init__(self, n, cost):
		self.parent = [i for i in range(n + 1)]
		self.rank = [1] * (n + 1)
		self.cost = cost
		self.visited = [0] * (n + 1)

	def find(self, x):
		if self.parent[x] != x:
			self.parent[x] = self.find(self.parent[x])
		return self.parent[x]

	def union(self, x, y):
		x_repr = self.find(x)
		y_repr = self.find(y)
		if x_repr == y_repr:
			return
		elif self.rank[x_repr] < self.rank[y_repr]:
			self.parent[x_repr] = y_repr
		elif self.rank[y_repr] < self.rank[x_repr]:
			self.parent[y_repr] = x_repr
		else:
			self.parent[x_repr] = y_repr
			self.rank[y_repr] += 1

	def populate_representatives(self, x):
		root = self.find(x)
		if 0 <= self.cost[x] < self.cost[root] or (self.cost[root] < 0 and self.cost[x] >= 0):
			self.cost[root] = self.cost[x]
(n, m) = map(int, input().strip().split())
connections = []
cost = [0] * (n + 1)
summ = 0
minimum = 100005
count = 0
not_possible = 0
for _ in range(m):
	(x, y) = map(int, input().strip().split())
	connections.append((x, y))
for _ in range(1, n + 1):
	cost[_] = int(input())
ds = DisjointSet(n, cost)
for i in connections:
	ds.union(i[0], i[1])
for _ in range(1, n + 1):
	ds.populate_representatives(_)
for i in range(1, n + 1):
	if not ds.visited[ds.parent[i]]:
		ds.visited[ds.parent[i]] = 1
		if ds.cost[ds.parent[i]] < 0:
			not_possible = 1
		summ += ds.cost[ds.parent[i]]
		minimum = min(minimum, ds.cost[ds.parent[i]])
		count += 1
if count != 1:
	if not_possible:
		print(-1)
	else:
		count = (count - 2) * minimum
		print(summ + count)
else:
	print(0)


from sys import stdin, stdout

def find(a):
	if par[a] == a:
		return a
	else:
		par[a] = find(par[a])
		return par[a]

def union(a, b):
	(a, b) = (find(a), find(b))
	if a != b:
		if rank[a] > rank[b]:
			par[b] = a
		elif rank[b] > rank[a]:
			par[a] = b
		else:
			par[a] = b
			rank[b] += 1
(n, m) = stdin.readline().strip().split(' ')
(n, m) = (int(n), int(m))
par = [i for i in range(n)]
rank = [0 for i in range(n)]
cost = [-1 for i in range(n)]
for i in range(m):
	(u, v) = stdin.readline().strip().split(' ')
	(u, v) = (int(u) - 1, int(v) - 1)
	union(u, v)
up = set()
for i in range(n):
	c = int(stdin.readline().strip())
	up.add(find(i))
	if c >= 0:
		if cost[find(i)] == -1:
			cost[find(i)] = c
		else:
			cost[find(i)] = min(cost[find(i)], c)
if len(up) == 1:
	print(0)
else:
	flag = True
	for i in up:
		if cost[i] == -1:
			print(-1)
			flag = False
			break
	if flag:
		t1 = [cost[x] for x in up]
		t1.sort()
		print(sum(t1) + (len(t1) - 2) * t1[0])


def find(child):
	if child == parents[child]:
		return parents[child]
	parents[child] = find(parents[child])
	return parents[child]

def union(root1, root2):
	(real_root1, real_root2) = (find(root1), find(root2))
	if real_root1 == real_root2:
		return
	if rank[real_root1] <= rank[real_root2]:
		parents[real_root1] = real_root2
		if rank[real_root1] == rank[real_root2]:
			rank[real_root2] += 1
	else:
		parents[real_root2] = real_root1
(n, m) = map(int, input().strip().split())
parents = list(range(n))
rank = [0 for i in range(n)]
for i in range(m):
	(root1, root2) = map(int, input().strip().split())
	union(root1 - 1, root2 - 1)
cost_dict = {}
for i in range(n):
	if i == parents[i]:
		cost_dict[i] = 10 ** 5
cost = [10 ** 5 for i in range(n)]
min_cost = 10 ** 5
for i in range(n):
	c = int(input().strip())
	if c >= 0:
		cost[i] = c
		grand_parent = find(i)
		cost_dict[grand_parent] = min(c, cost_dict[grand_parent])
		min_cost = min(c, min_cost)
possible = True
total_cost = 0
for root in cost_dict:
	cst = cost_dict[root]
	if cst == 10 ** 5 or cst > 10 ** 4:
		possible = False
		break
	else:
		total_cost += cst
if len(cost_dict) == 1:
	print(0)
elif not possible:
	print(-1)
else:
	total_cost = total_cost + (len(cost_dict) - 2) * min_cost
	print(total_cost)


def find_root(arr, n):
	while arr[n] != n:
		n = arr[n]
	return n

def union(arr, a, b, size):
	root_a = find_root(arr, a)
	root_b = find_root(arr, b)
	if root_a == root_b:
		return
	if size[root_a] < size[root_b]:
		arr[root_a] = arr[root_b]
		size[root_b] += arr[root_a]
	else:
		arr[root_b] = arr[root_a]
		size[root_a] += size[root_b]

def same_root(arr, i, cost):
	root = find_root(arr, i)
	if cost[i] < cost[root] and cost[i] > -1 or (cost[root] < 0 and cost[i] > -1):
		cost[root] = cost[i]
	arr[i] = root
(N, M) = [int(x) for x in input().split()]
size = [1] * (N + 1)
arr = [x for x in range(N + 1)]
cost = [0]
while M > 0:
	(a, b) = [int(x) for x in input().split()]
	union(arr, a, b, size)
	M -= 1
temp = N
while temp > 0:
	cost.append(int(input()))
	temp -= 1
for i in range(1, N + 1):
	same_root(arr, i, cost)
roots_dict = {}
sum = 0
cnt = 0
min = 1000000
flag = True
for i in range(1, N + 1):
	if arr[i] not in roots_dict:
		if cost[arr[i]] < 0:
			flag = False
		sum += cost[arr[i]]
		if cost[arr[i]] < min:
			min = cost[arr[i]]
		roots_dict[arr[i]] = True
		cnt += 1
if cnt == 1:
	print('0')
elif flag:
	print(sum + (cnt - 2) * min)
else:
	print('-1')


def find(a):
	if par[a] == a:
		return a
	else:
		par[a] = find(par[a])
		return par[a]

def union(a, b):
	(a, b) = (find(a), find(b))
	if a != b:
		if rank[a] > rank[b]:
			par[b] = a
		elif rank[b] > rank[a]:
			par[a] = b
		else:
			par[a] = b
			rank[b] += 1
(n, m) = map(int, input().split())
par = [i for i in range(n + 1)]
rank = [0 for i in range(n + 1)]
cost = [-1 for i in range(n + 1)]
for i in range(m):
	(u, v) = map(int, input().split())
	union(u, v)
up = set()
for i in range(1, n + 1):
	c = int(input())
	up.add(find(i))
	if c >= 0:
		if cost[find(i)] == -1:
			cost[find(i)] = c
		else:
			cost[find(i)] = min(cost[find(i)], c)
if len(up) == 1:
	print(0)
else:
	flag = True
	for i in up:
		if cost[i] == -1:
			print(-1)
			flag = False
			break
	if flag:
		t1 = [cost[x] for x in up]
		t1.sort()
		print(sum(t1) + (len(t1) - 2) * t1[0])


def find(child):
	if child == parents[child]:
		return parents[child]
	parents[child] = find(parents[child])
	return parents[child]

def union(r1, r2):
	(mr1, mr2) = (find(r1), find(r2))
	if mr1 == mr2:
		return
	if rank[mr1] <= rank[mr2]:
		parents[mr1] = mr2
		if rank[mr1] == rank[mr2]:
			rank[mr2] += 1
	else:
		parents[mr2] = mr1
(n, m) = map(int, input().split())
parents = list(range(n))
rank = [0 for i in range(n)]
for i in range(m):
	(r1, r2) = map(int, input().strip().split())
	union(r1 - 1, r2 - 1)
cost_dict = {}
for i in range(n):
	if i == parents[i]:
		cost_dict[i] = 10 ** 5
cost = [10 ** 5 for i in range(n)]
min_cost = 10 ** 5
for i in range(n):
	c = int(input().strip())
	if c >= 0:
		cost[i] = c
		grand_parent = find(i)
		cost_dict[grand_parent] = min(c, cost_dict[grand_parent])
		min_cost = min(c, min_cost)
possible = True
total_cost = 0
for r in cost_dict:
	cst = cost_dict[r]
	if cst == 10 ** 5 or cst > 10 ** 4:
		possible = False
		break
	else:
		total_cost += cst
if len(cost_dict) == 1:
	print(0)
elif not possible:
	print(-1)
else:
	total_cost = total_cost + (len(cost_dict) - 2) * min_cost
	print(total_cost)


from sys import stdin, stdout

def find(parent, n):
	if parent[n] == n:
		return n
	else:
		parent[n] = find(parent, parent[n])
		return parent[n]

def union(parent, u, v):
	(u, v) = (find(parent, u), find(parent, v))
	if u != v:
		if rank[u] > rank[v]:
			parent[v] = u
		elif rank[u] < rank[v]:
			parent[u] = v
		else:
			parent[u] = v
			rank[v] += 1
(n, m) = stdin.readline().strip().split(' ')
(n, m) = (int(n), int(m))
parent = [i for i in range(n)]
rank = [0] * n
choice = [-1 for i in range(n)]
for _ in range(m):
	(u, v) = stdin.readline().strip().split(' ')
	(u, v) = (int(u) - 1, int(v) - 1)
	union(parent, u, v)
s = set()
for i in range(n):
	c = int(stdin.readline().strip())
	s.add(find(parent, i))
	if c >= 0:
		if choice[find(parent, i)] == -1:
			choice[find(parent, i)] = c
		else:
			choice[find(parent, i)] = min(choice[find(parent, i)], c)
if len(s) == 1:
	print(0)
else:
	f = 0
	for i in s:
		if choice[i] == -1:
			print(-1)
			f = 1
			break
	if f == 0:
		t = [choice[x] for x in s]
		t.sort()
		print(sum(t) + (len(t) - 2) * t[0])