Problem: 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.

Examples

Input

2
1 2 1 2 2 1


Output

2


Input

3
1 1 2 2 3 3 3 2 1


Output

1


Input

3
1 1 2 2 2 3 3 3 1


Output

3

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ld long double

int main(){
    int N;
    cin >> N;
    vector<int> A(3*N+1, 0);
    for (int i = 1; i <= 3*N; i++) cin >> A[i];
    vector<vector<int>> dp(N+1, vector<int>(N+1, -1e8));
    dp[A[1]][A[2]] = 0;
    dp[A[2]][A[1]] = 0;
    
    int geta = 0;
    queue<pair<pair<int, int>, int>> renew;
    vector<int> onemax(N+1, -1e8);
    onemax[A[1]] = 0;
    onemax[A[2]] = 0;
    int nowmax = 0;
    for (int i = 1; i <= N-1; i++) {
        int c = min(A[3*i], min(A[3*i+1], A[3*i+2]));
        int e = max(A[3*i], max(A[3*i+1], A[3*i+2]));
        int d = A[3*i]+A[3*i+1]+A[3*i+2]-c-e;
        
        if (c == d && d == e) {
            geta++;
            continue;
        }else if (c == d || d == e) {
            if (d == e) swap(c, e);
            
            for (int i = 1; i <= N; i++) {
                renew.push({{e, i}, dp[c][i]+1});
            }
            renew.push({{c, c}, nowmax});
            renew.push({{c, c}, dp[e][e]+1});
            renew.push({{c, e}, nowmax});
            for (int i = 1; i <= N; i++) {
                renew.push({{c, i}, onemax[i]});
                renew.push({{e, i}, onemax[i]});
            }
        }else {
            renew.push({{d, e}, max(dp[c][c]+1, nowmax)});
            renew.push({{c, e}, max(dp[d][d]+1, nowmax)});
            renew.push({{c, d}, max(dp[e][e]+1, nowmax)});
            for (int i = 1; i <= N; i++) {
                renew.push({{c, i}, onemax[i]});
                renew.push({{d, i}, onemax[i]});
                renew.push({{e, i}, onemax[i]});
            }
        }
        while (!renew.empty()) {
            auto p = renew.front();
            int a = p.first.first, b = p.first.second;
            int v = p.second;
            renew.pop();
            onemax[a] = max(onemax[a], v);
            onemax[b] = max(onemax[b], v);
            nowmax = max(nowmax, v);
            dp[a][b] = max(dp[a][b], v);
            dp[b][a] = max(dp[b][a], v);
        }
    }
    cout << max(nowmax, dp[A[3*N]][A[3*N]]+1)+geta << endl;
	return 0;
}