Problem:
Problem D: Luigi's Tavern

Luigi's Tavern is a thriving tavern in the Kingdom of Nahaila. The owner of the tavern Luigi supports to
organize a party, because the main customers of the tavern are adventurers. Each adventurer has a job:
hero, warrior, cleric or mage.

Any party should meet the following conditions:

A party should have a hero.

The warrior and the hero in a party should get along with each other.

The cleric and the warrior in a party should get along with each other.

The mage and the cleric in a party should get along with each other.

It is recommended that a party has a warrior, a cleric, and a mage, but it is allowed that at most
NW, NC and Nm parties does not have a warrior, a cleric, and a mage respectively.

A party without a cleric should have a warrior and a mage.

Now, the tavern has H heroes, W warriors, C clerics and M mages. Your job is to write a program to find the maximum number of parties they can form.

Input

The input consists of multiple datasets. Each dataset has the following format:

The first line of the input contains 7 non-negative integers H, W, C, M, NW, NC, and NM, each of which is less than or equals to 50. The i-th of the following W lines contains the list of heroes who will be getting along with the warrior i. The list begins with a non-negative integer ni , less than or equals to H. Then the rest of the line should contain ni positive integers, each of which indicates the ID of a hero getting along with the warrior i.

After these lists, the following C lines contain the lists of warriors getting along with the clerics in the same manner. The j-th line contains a list of warriors who will be getting along with the cleric j. Then the last M lines of the input contain the lists of clerics getting along with the mages, of course in the same
manner. The k-th line contains a list of clerics who will be getting along with the mage k.

The last dataset is followed by a line containing seven negative integers. This line is not a part of any dataset and should not be processed.

Output

For each dataset, you should output the maximum number of parties possible.

Sample Input

2 1 1 1 1 1 1
1 1
1 1
1 1
1 1 1 1 0 0 0
1 1
1 1
1 1
1 0 1 0 1 0 1
0
1 1 0 1 0 1 0
0
0
1 1 0 1 0 1 0
1 1
0
-1 -1 -1 -1 -1 -1 -1

Output for the Sample Input

2
1
1
0
1

Solution in Ruby (judge verdict: Accepted)

require 'set'

def get_path(g, u, t, reached = Set[u])
	return [t] if u == t

	g[u].each do |v|
		next if reached.include?(v)
		reached << v
		if path = get_path(g, v, t, reached)
			return [u] + path 
		end
	end
	return nil
end

loop do
	params = gets.split.map(&:to_i)
	h, w, c, m, nw, nc, nm = params
	break if h == -1

	node_num = params.inject(:+) * 2 - h + 2

	g = (0..node_num-1).map { Set.new }

	id = 0
	s = id
	heros = (1..h).map { id += 1 }
	warriors_in = (1..w).map { id += 1 }
	warriors_out = (1..w).map { id += 1 }
	dummy_warriors_in = (1..nw).map { id += 1 }
	dummy_warriors_out = (1..nw).map { id += 1 }
	clerics_in = (1..c).map { id += 1 }
	clerics_out = (1..c).map { id += 1 }
	dummy_clerics_in = (1..nc).map { id += 1 }
	dummy_clerics_out = (1..nc).map { id += 1 }
	mages_in = (1..m).map { id += 1 }
	mages_out = (1..m).map { id += 1 }
	dummy_mages_in = (1..nm).map { id += 1 }
	dummy_mages_out = (1..nm).map { id += 1 }
	t = (id += 1)

	heros.each do |j|
		g[s] << j
	end

	warriors_in.each do |j|
		_, *hs = gets.split.map(&:to_i)
		hs.each do |l|
			i = heros[l-1]
			g[i] << j
		end
	end

	warriors_in.zip(warriors_out).each do |i, j|
		g[i] << j
	end

	dummy_warriors_in.each do |j|
		heros.each do |i|
			g[i] << j
		end
	end

	dummy_warriors_out.each do |i|
		clerics_in.each do |j|
			g[i] << j
		end
	end

	dummy_warriors_in.zip(dummy_warriors_out).each do |i, j|
		g[i] << j
	end

	clerics_in.each do |j|
		_, *ws = gets.split.map(&:to_i)
		ws.each do |l|
			i = warriors_out[l-1]
			g[i] << j
		end
	end

	clerics_in.zip(clerics_out).each do |i, j|
		g[i] << j
	end

	dummy_clerics_in.each do |j|
		warriors_out.each do |i|
			g[i] << j
		end
	end

	dummy_clerics_out.each do |i|
		mages_in.each do |j|
			g[i] << j
		end
	end

	dummy_clerics_in.zip(dummy_clerics_out).each do |i, j|
		g[i] << j
	end

	mages_in.each do |j|
		_, *cs = gets.split.map(&:to_i)
		cs.each do |l|
			i = clerics_out[l-1]
			g[i] << j
		end
	end

	mages_out.each do |j|
		g[j] << t
	end

	mages_in.zip(mages_out).each do |i, j|
		g[i] << j
	end

	dummy_mages_in.each do |j|
		clerics_out.each do |i|
			g[i] << j
		end
	end
	
	dummy_mages_out.each do |j|
		g[j] << t
	end

	dummy_mages_in.zip(dummy_mages_out).each do |i, j|
		g[i] << j
	end


	flow = 0
	loop do
		break unless path = get_path(g, s, t)
		flow += 1
		path.reverse.each_cons(2) do |j, i|
			g[i].delete(j)
			g[j] << i
		end
	end
	p flow
end