// Arup Guha
// 2/13/2017
// Solution to German Programming Contest Problem K: Routing

import java.util.*;

public class k {

	public static int n;
	public static edge[][] graph;
	public static int[] weights;
	public static boolean[][][] forbidden;

	public static void main(String[] args) {

		Scanner stdin = new Scanner(System.in);
		n = stdin.nextInt();
		graph = new edge[n][];
		weights = new int[n];
		forbidden = new boolean[n][][];

		// Go through each set of edges from each vertex.
		for (int i=0; i<n; i++) {

			int numE = stdin.nextInt();
			weights[i] = stdin.nextInt();
			graph[i] = new edge[numE];
			forbidden[i] = new boolean[numE][];

			// Now, go through each edge from this vertex.
			for (int j=0; j<numE; j++) {
				int numBad = stdin.nextInt();
				int next = stdin.nextInt()-1;
				forbidden[i][j] = new boolean[n];
				for (int k=0; k<numBad; k++)
					forbidden[i][j][stdin.nextInt()-1] = true;
				graph[i][j] = new edge(i, next, 0);
			}
		}

		// Now we can set the weights.
		for (int i=0; i<n; i++)
			for (int j=0; j<graph[i].length; j++)
				graph[i][j].w = weights[graph[i][j].v2];

		int res = dijkstras();

		// Output the result.
		if (res >= 1000000000)
			System.out.println("impossible");
		else
			System.out.println(res+weights[0]);
	}

	public static int dijkstras() {

		// Set up the priority queue.
		PriorityQueue<edge> pq = new PriorityQueue<edge>();

		// Initial estimates. dist[i][j] stores shortest distance to j with last edge coming through i.
		edge[][] dist = new edge[n][n];
		for (int i=0; i<n; i++)
			for (int j=0; j<n; j++)
				dist[i][j] = new edge(i,j,1000000000);

		// None of these are forbidden put them in.
		for (int i=0; i<graph[0].length; i++)
			dist[0][graph[0][i].v2].w = graph[0][i].w;
		for (int i=0; i<n; i++)
			for (int j=0; j<n; j++)
				pq.offer(dist[i][j]);

		// Store which ones we have the shortest distance to.
		boolean[][] done = new boolean[n][n];

		// run till we're done.
		while (pq.size() > 0) {

			// Pull the next shortest distance to build off of.
			edge cur = pq.poll();
			int at = cur.v2;
			done[cur.v1][cur.v2] = true;

			// Made it to the end!
			if (at == n-1) return cur.w;

			// Enqueue next, skipping forbidden.
			for (int i=0; i<graph[at].length; i++) {
				int next = graph[at][i].v2;

				// Can't be forbidden and destination must be something we don't have the shortest distance to.
				if (!forbidden[at][i][cur.v1] && !done[cur.v2][next]) {

					// Update and add to queue - be careful so queue doesn't grow too big. Find node, remove and put back in.
					if (dist[cur.v1][cur.v2].w + weights[next] < dist[cur.v2][next].w) {
						pq.remove(dist[cur.v2][next]);
						dist[cur.v2][next].w = dist[cur.v1][cur.v2].w + weights[next];
						pq.offer(dist[cur.v2][next]);
					}
				}
			}
		}

		// Not found.
		return -1;

	}
}

class edge implements Comparable<edge> {

	public int v1;
	public int v2;
	public int w;

	public edge(int from, int to, int myW) {
		v1 = from;
		v2 = to;
		w = myW;
	}

	public int compareTo(edge other) {
		return this.w - other.w;
	}
}