#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <vector>
#include <stack>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <fstream>

#define MAX_TOWERS			100
#define MAX_CONNECTIONS		100
#define MAX_DEFENSE			50
#define MAX_CHANNELS		5000

using namespace std;

typedef struct {
	int id;
	int tid[2];
	int defense;
	bool alive;
} Channel;

typedef struct {
	int id, defense;
	int connected[MAX_CONNECTIONS];
	int channelCount;
	int channelids[MAX_CONNECTIONS];
} Tower;

void solve(void);
void createChannelList(void);
int doMaximumSpanningTree(void);

#define fin cin

//ifstream fin;
int testcase;
int towerCount, channelCount;
Tower towers[MAX_TOWERS];
Channel channels[MAX_CHANNELS];
Channel sortedChannels[MAX_CHANNELS];

int main(void) {
	int n;
//	fin.open("e.in");
    fin >> n;
    
	for (testcase = 1; testcase < n + 1; testcase++)
		solve();
	
//	fin.close();
}

void solve(void) {
	fin >> towerCount;
	
	for (int i = 0; i < towerCount; i++) {
		Tower t;
		fin >> t.id >> t.defense >> t.channelCount;
		for (int j = 0; j < t.channelCount; j++) {
			fin >> t.connected[j];
		}
		towers[t.id] = t;
	}
	
	createChannelList();
	cout << doMaximumSpanningTree() << "\n";
}

// Channels are equal if both contain the same towers
inline bool equals(Channel c1, Channel c2) {
	return	(c1.tid[0] == c2.tid[0] && c1.tid[1] == c2.tid[1]) ||
			(c1.tid[0] == c2.tid[1] && c1.tid[1] == c2.tid[0]);
}

// Function used to sort the channels
inline bool channelBeforeOther(Channel c1, Channel c2) { 
	return c1.defense > c2.defense; 
}

int qchannelBeforeOther(const void* c1, const void* c2) { 
	return ((const Channel*)c2)->defense - ((const Channel*)c1)->defense; 
}

inline int getChannelWithid(int id) {
	for (int i = 0; i < channelCount; i++) {
		if ( channels[i].id == id )
			return i;
	}
	return -1;
}

void createChannelList(void) {
	channelCount = 0;
	/* Go through all the towers and add a channel to the channellist for each connection.
	 * However, we must ignore half of the channels: in the given graph, 
	 * each connection is listed two times (once for each direction).
	 */
	for (int i = 0; i < towerCount; i++) {
		// A tower can have one or more connections; Each connection is a channel
		int towerChannelCount = 0;
		for (int j = 0; j < towers[i].channelCount; j++) {
			// A channel always connects two towers
			Channel c;
			c.tid[0] = towers[i].id;
			c.tid[1] = towers[i].connected[j];
			int channelKnown = -1;
			
			// Only add this channel to the list if it's not in the list already
			for (int k = 0; k < channelCount; k++) {
				if ( equals(c, channels[k]) ) {
					channelKnown = k;
					break;
				}
			}
			if (channelKnown != -1) {
				// The channel is on the list and the tower must know about the connection through this channel
				towers[i].channelids[towerChannelCount++] = channelKnown;
				continue; // This channel is already in the list
			}
			
			c.defense = towers[i].defense + towers[c.tid[1]].defense; // Calculate defense of the channel
			c.alive = false; // Presume that alle channels are destroyed as a starting point
			c.id = channelCount;
			channels[channelCount++] = c; // Add the channel to the list
			towers[i].channelids[towerChannelCount++] = c.id;
		}
		towers[i].channelCount = towerChannelCount;
	}
}

bool cycleFound;
bool searchedTowers[MAX_TOWERS];
bool searchedChannels[MAX_CHANNELS];
// Search for a cycle in the graph and set 'cycleFound' accordingly if one is found
void searchForCycle(int currentTower) {
	if (cycleFound) return; // Do not continue searching if we already found a cycle

	// We reached a tower we've already passed so we found a cycle
	if (searchedTowers[currentTower]) {
		cycleFound = true;
		return;
	}
	
	// Look at all the channels of this tower and see to what towers they connect
	Tower t = towers[currentTower];
	searchedTowers[currentTower] = true; // We've seen this tower in our search
	for (int i = 0; i < t.channelCount; i++) {
		int id = t.channelids[i];
		Channel c = channels[id];
		// A destroyed channel, or one already visited should be ignored
		if (!c.alive || searchedChannels[id]) continue;
		
		searchedChannels[id] = true; // Soon we'll have visited this channel
		// See what tower is on the other side and continue the search there
		if (c.tid[0] != currentTower)
			searchForCycle(c.tid[0]);
		else
			searchForCycle(c.tid[1]);
	}

}

int doMaximumSpanningTree(void) {
	int towersConnected = 0;
	int currentChannel = 0;
	// Sort channels on defense
//	sort(channels, channels + channelCount channelBeforeOther);
	qsort(channels, channelCount, sizeof(Channel), qchannelBeforeOther);
	
	// Let the towers know their channels now that the list has been sorted
	for (int i = 0; i < towerCount; i++)
		for (int j = 0; j < towers[i].channelCount; j++)
			towers[i].channelids[j] = getChannelWithid(towers[i].channelids[j]);


	// Do maximum spanning tree
	while (currentChannel < channelCount) {
		// Clear up everything before doing a cycle-search
		for (int i = 0; i < towerCount; i++)
			searchedTowers[i] = false;
		for (int i = 0; i < channelCount; i++)
			searchedChannels[i] = false;
		cycleFound = false;
		
		// Try to let this channel live and see if there are any cycles
		channels[currentChannel].alive = true;
		int currentTower = channels[currentChannel].tid[0];
		searchForCycle(currentTower);
		if (cycleFound) {
			// We found a cycle, so we cannot let this channel live
			channels[currentChannel].alive = false;
		}

		currentChannel++; // Continue searching
	}
	
	// The cost is the total of the defenses of the destroyed channels
	int totalCost = 0;
	for (int i = 0; i < channelCount; i++)
		if (!channels[i].alive) totalCost += channels[i].defense;
		
	return totalCost;
}
