#include #include #include #include #define MAXN 10 #define MAXVAL 9 using namespace std; int n; int len[MAXN + 1]; int a[MAXN + 1][MAXVAL + 1]; int a_mask[MAXN + 1]; bool transition[MAXN + 1][MAXVAL + 1][MAXN + 1]; int stay_mask[MAXN + 1][MAXVAL + 1]; bool Transition(int x, int xi, int y) { if (a_mask[y] & ~a_mask[x]) return false; for (int yi = 0; yi < len[y]; ++yi) { if (a[y][yi] == a[x][xi]) ++xi; } return xi == len[x]; } int StayMask(int x, int xi) { int mask = 0; for (int i = 0; i < xi; ++i) { mask |= 1 << a[x][i]; } return mask; } const int oo = MAXN * MAXVAL + 1; char memo[MAXN + 1][MAXVAL + 1][MAXN + 1][MAXVAL + 1][1 << MAXN]; int Rec(int l, int li, int r, int ri, int used_mask) { used_mask &= (1 << n) - 1; if (li == 0 && ri == len[r] && used_mask == (1 << n) - 1) return 0; if (memo[l][li][r][ri][used_mask] >= 0) return memo[l][li][r][ri][used_mask]; int ret = oo; if (l != n && li == 0) { for (int i = 0; i <= n; ++i) { if ((used_mask >> i) & 1) continue; for (int j = 0; j <= len[i]; ++j) { if (!transition[i][j][l]) continue; ret = min(ret, Rec(i, j, r, ri, used_mask | (1 << i))); } } } else { for (int i = 0; i < n; ++i) { if ((used_mask >> i) & 1) continue; if (!transition[r][ri][i]) continue; ret = min(ret, Rec(l, li, i, 0, used_mask | (1 << i))); } for (int val = 1; val <= MAXVAL; ++val) { if (val == a[l][li - 1] && val == a[r][ri]) { ret = min(ret, 1 + Rec(l, li - 1, r, ri + 1, used_mask)); } if (val == a[l][li - 1] && ((stay_mask[r][ri] >> val) & 1)) { ret = min(ret, 1 + Rec(l, li - 1, r, ri, used_mask)); } if (((stay_mask[l][li] >> val) & 1) && val == a[r][ri]) { ret = min(ret, 1 + Rec(l, li, r, ri + 1, used_mask)); } } } return memo[l][li][r][ri][used_mask] = ret; } int main() { scanf("%d", &n); for (int i = 0; i < n; ++i) { for (len[i] = 0;; ++len[i]) { scanf("%d", &a[i][len[i]]); if (a[i][len[i]] == 0) break; a_mask[i] |= (1 << a[i][len[i]]); } } len[n] = 0; for (int x = 0; x <= n; ++x) { for (int xi = 0; xi <= len[x]; ++xi) { if (x == n) { stay_mask[x][xi] = (1 << (MAXVAL + 1)) - 1; } else { stay_mask[x][xi] = StayMask(x, xi); } for (int y = 0; y <= n; ++y) { if (x == y) continue; if (x == n) transition[x][xi][y] = true; else transition[x][xi][y] = Transition(x, xi, y); } } } memset(memo, -1, sizeof memo); int ret = oo; for (int i = 0; i <= n; ++i) { int result = Rec(i, len[i], n, 0, (1 << i)); if (result < ret) ret = result; } if (ret == oo) printf("-1\n"); else printf("%d\n", ret); return 0; }