// Arup Guha
// 3/9/2018
// Solution to 2018 February USACO Gold Problem: Directory Traversal

import java.io.*;
import java.util.*;

public class dirtraverse {

	public static int n;
	public static node[] tree;

	public static void main(String[] args) throws Exception {

		// Read the data.
		BufferedReader stdin = new BufferedReader(new FileReader("dirtraverse.in"));
		StringTokenizer tok = new StringTokenizer(stdin.readLine());
		n = Integer.parseInt(tok.nextToken());
		tree = new node[n];

		// Go through each node.
		for (int i=0; i<n; i++) {

			tok = new StringTokenizer(stdin.readLine());
			int nameLen = tok.nextToken().length();

			// See if it's a file or directory.
			int k = Integer.parseInt(tok.nextToken());

			// File case.
			if (k == 0)
				tree[i] = new node(i, nameLen);

			// Directory case.
			else {
				ArrayList<Integer> kids = new ArrayList<Integer>();
				for (int j=0; j<k; j++)
					kids.add(Integer.parseInt(tok.nextToken())-1);
				tree[i] = new node(i, nameLen, kids);
			}
		}


		LinkedList<Integer> q = new LinkedList<Integer>();
		q.offer(0);

		// Do a BFS to set the depths.
		while (q.size() > 0) {

			// Get this node.
			int cur = q.poll();
			int curD = tree[cur].depth;

			// This is null if there are no kids...
			if (tree[cur].kids == null) continue;

			// Set its kids' depths.
			for (Integer x : tree[cur].kids) {
				q.offer(x);
				tree[x].depth = curD + 1;
			}
		}

		// Sort in order of depth from most to least.
		node[] alt = new node[n];
		for (int i=0; i<n; i++) alt[i] = tree[i];
		Arrays.sort(alt);

		// This will fill in the # leaf nodes and dist to leaves.
		for (int i=0; i<n; i++) {
			int cur = alt[i].ID;
			if (tree[cur].kids == null) continue;

			// Go through kids update leaf nodes and distance to them.
			for (int j=0; j<tree[cur].kids.size(); j++) {
				int kid = tree[cur].kids.get(j);
				int add = tree[kid].kids == null ? 0 : 1;
				tree[cur].numLeaf += tree[kid].numLeaf;
				tree[cur].distToLeaf += ( tree[kid].distToLeaf + (tree[kid].nameLen + add)*tree[kid].numLeaf);
			}
		}

		// Solve by getting the answer at each node.
		long res = go(0, tree[0].distToLeaf);

		// Ta da!
		PrintWriter out = new PrintWriter(new FileWriter("dirtraverse.out"));
		out.println(res);
		out.close();
		stdin.close();
	}

	public static long go(int node, long curres) {

		// Base case.
		if (tree[node].kids == null) return curres;

		long myres = curres;

		// Try each kid.
		for (int j=0; j<tree[node].kids.size(); j++) {
			int kid = tree[node].kids.get(j);
			long savings = tree[kid].numLeaf*(tree[kid].nameLen + 1) - (tree[0].numLeaf-tree[kid].numLeaf)*3;
			myres = Math.min(myres, go(kid, curres-savings));
		}

		// Return the best.
		return myres;
	}
}

class node implements Comparable<node> {

	public int nameLen;
	public int ID;
	public int depth;
	public int numLeaf;
	public long distToLeaf;
	public ArrayList<Integer> kids;

	public node(int num, int name, ArrayList<Integer> next) {
		ID = num;
		nameLen = name;
		numLeaf = 0;
		distToLeaf = 0;
		kids = next;
		depth = 0;
	}

	public String toString() {
		return ID+" d= "+depth+" nL= "+numLeaf+" distToL= "+distToLeaf;
	}

	public node(int num, int name) {
		ID = num;
		nameLen = name;
		numLeaf = 1;
		distToLeaf = 0;
		kids = null;
		depth = 0;
	}

	public int compareTo(node other) {
		return other.depth - this.depth;
	}
}