Problem:
Score : 600 points

Problem Statement

We have 3N cards arranged in a row from left to right, where each card has an integer between 1 and N (inclusive) written on it. The integer written on the i-th card from the left is A_i.

You will do the following operation N-1 times:

Rearrange the five leftmost cards in any order you like, then remove the three leftmost cards. If the integers written on those three cards are all equal, you gain 1 point.

After these N-1 operations, if the integers written on the remaining three cards are all equal, you will gain 1 additional point.

Find the maximum number of points you can gain.

Constraints

1 \leq N \leq 2000

1 \leq A_i \leq N

Input

Input is given from Standard Input in the following format:

N
A_1 A_2 \cdots A_{3N}

Output

Print the maximum number of points you can gain.

Sample Input 1

2
1 2 1 2 2 1

Sample Output 1

2

Let us rearrange the five leftmost cards so that the integers written on the six cards will be 2\ 2\ 2\ 1\ 1\ 1 from left to right.

Then, remove the three leftmost cards, all of which have the same integer 2, gaining 1 point.

Now, the integers written on the remaining cards are 1\ 1\ 1.

Since these three cards have the same integer 1, we gain 1 more point.

In this way, we can gain 2 points - which is the maximum possible.

Sample Input 2

3
1 1 2 2 3 3 3 2 1

Sample Output 2

1

Sample Input 3

3
1 1 2 2 2 3 3 3 1

Sample Output 3

3

Solution in Java (OpenJDK 11.0.6) (judge verdict: Time Limit Exceeded)


import java.util.Arrays;
import java.util.Scanner;
import java.util.Set;

public class Main {
    
    private static final Set<int[]> patterns = Set.of(
            new int[] { 0, 1, 2, 3, 4 },
            new int[] { 0, 1, 3, 2, 4 },
            new int[] { 0, 1, 4, 2, 3 },
            new int[] { 0, 2, 3, 1, 4 },
            new int[] { 0, 2, 4, 1, 3 },
            new int[] { 0, 3, 4, 1, 2 },
            new int[] { 1, 2, 3, 0, 4 },
            new int[] { 1, 2, 4, 0, 3 },
            new int[] { 1, 3, 4, 0, 2 },
            new int[] { 2, 3, 4, 0, 1 });
    
    private static int[] As;
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        
        final int N = sc.nextInt();
        As = new int[N * 3];
        for (int i = 0; i < N * 3; i++) {
            As[i] = sc.nextInt();
        }
        
        System.out.println(calc(0, Arrays.copyOf(As, 2)));
    }
    
    private static int calc(int start, int[] left2) {
        if (start + 3 == As.length) {
            return left2[0] == As[start + 2] && left2[1] == As[start + 2] ? 1 : 0;
        }
        
        int[] left5 = new int[] { left2[0], left2[1], As[start + 2], As[start + 3], As[start + 4] };
        
        return patterns.stream().map(p -> {
            int[] l5 = new int[5];
            l5[0] = left5[p[0]];
            l5[1] = left5[p[1]];
            l5[2] = left5[p[2]];
            l5[3] = left5[p[3]];
            l5[4] = left5[p[4]];
            
            Arrays.sort(l5, 0, 3);
            Arrays.sort(l5, 3, 5);
            
            return l5;
        })
                .distinct()
                .parallel()
                .mapToInt(l5 -> {
                    int curr = (l5[0] == l5[1] && l5[0] == l5[2] ? 1 : 0);
                    int next = calc(start + 3, new int[] { l5[3], l5[4] });
                    return curr + next;
                }).max().getAsInt();
    }
}