#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 45;
int pile[MAXN][5]; //堆
int num[5]; //各堆中堆顶元素位置
int dp[MAXN][MAXN][MAXN][MAXN];
int n;
//深搜,basket表示篮子中糖果的状态,cnt表示篮子中糖果的数量
int DFS(int basket, int cnt)
{
if (dp[num[1]][num[2]][num[3]][num[4]] != -1)
return dp[num[1]][num[2]][num[3]][num[4]];
int maxTotal = 0; //能得到的最大糖果对数
for (int i = 1; i <= 4; i++)
{
int total = 0; //当前得到的糖果对数
num[i]++;
if (num[i] <= n)
{
int candy = (1 << pile[num[i]][i]);
if (basket & candy) //篮子中有和当前糖果同色的糖果
total = DFS(basket & (~candy), cnt - 1) + 1;
else if (cnt < 4)
total = DFS(basket | candy, cnt + 1);
}
if (total > maxTotal)
maxTotal = total;
num[i]--;
}
dp[num[1]][num[2]][num[3]][num[4]] = maxTotal;
return maxTotal;
}
int main()
{
while (cin >> n)
{
if (n == 0)
break;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= 4; j++)
cin >> pile[i][j];
}
memset(num, 0, sizeof(num));
memset(dp, -1, sizeof(dp));
cout << DFS(0, 0) << endl;
}
return 0;
}