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 C++ (GCC 9.2.1) (judge verdict: Runtime Error)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define vi vector<ll>
#define pb push_back
#define eb emplace_back
#define rep2(i, a, b) for(ll i = a; i <= b; ++i)
#define rep(i, n) for(ll i = 0; i < n; ++i)
#define rep3(i, a, b) for(ll i = a; i >= b; --i)
template<class T, class S> inline bool chmax(T &a, S b) {if(a < b) {a = b;return 1;}return 0;}
int cnt[2010],dp[2010][2010],b[3];
int ma=1,ma2[2010],lazy=-1;
int main()
{
    int n;
    cin>>n;
    vector<int> a(n+3);
    a.push_back(0);
    a.push_back(0);
    rep(i, 5) rep2(j, i + 1, 4) {
        vi bb;
        rep(k, 5) if(k != i and k != j) bb.eb(a[k]);
        if(bb == vi(3, bb[0]))
            dp[a[i]][a[j]] = dp[a[j]][a[i]] = 2, ma = 2, ma2[a[i]] = ma2[a[j]] = 2;
        else
            dp[a[i]][a[j]] = dp[a[j]][a[i]] = 1, chmax(ma2[a[i]], 1), chmax(ma2[a[j]], 1);
    }
    vector<tuple<int, int, int>> mem;
    rep(i, n - 1) {
        int st = i * 3 + 5;
        if(a[st] == a[st + 1] and a[st] == a[st + 2]) {
            lazy++;
            continue;
        }
        rep(j, 3) b[j] = a[st + j];
        sort(b, b + 3);
        do {
            int K = max({dp[b[0]][b[1]], dp[b[2]][b[2]] + 1, ma});
            mem.eb(b[0], b[1], K);
            rep2(i, 1, n) {
                K = dp[i][b[0]];
                if(b[1] == b[2]) { chmax(K, dp[i][b[1]] + 1); }
                chmax(K, ma2[i]);
                mem.eb(i, b[0], K), mem.eb(b[0], i, K);
            }
        } while(next_permutation(b, b + 3));
        for(auto [e, f, g] : mem) chmax(dp[e][f], g), chmax(ma2[e], g), chmax(ma, g);
        mem.clear();
    }
    cout << ma + lazy << endl;
    return 0;
}