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 Rust (1.42.0) (judge verdict: Wrong Answer)

use std::io::Read;
use std::cmp::max;

fn main() {
  let mut buf = String::new();
  std::io::stdin().read_to_string(&mut buf).unwrap();
  let mut S : Vec<usize> = buf.split_whitespace().map(|s| s.parse().unwrap()).collect();
  let N = S[0];
  let mut S = S.split_off(1);
  
  let mut base = 0;
  let mut dp1 = vec![None; N + 1];
  let mut dp2 = vec![vec![None; N + 1];N + 1];
  let mut q = Vec::new();
  
  {
    let s = &mut S[0 .. 2];
    s.sort();
    {
      let (a,b) = (s[0], s[1]);
      dp1[a] = Some(0);
      dp1[b] = Some(0);
      dp1[0] = Some(0);
      dp2[a][b] = Some(0);
      
    }

    for i in 1 .. N {
      let s = &mut S[3 * i - 1 .. 3 * i + 2];
      s.sort();
      let (a,b,c) = (s[0],s[1],s[2]);
      
      if a == c {
        base += 1;
        continue;
      } else if a == b {
        for x in 1 ..= N {
          if x < a {
            if let Some(v) = dp2[x][a] {
              q.push((x, c, v + 1));
            }
          } else if x < c {
            if let Some(v) = dp2[a][x] {
              q.push((x, c, v + 1));
            }
          } else {
            if let Some(v) = dp2[a][x] {
              q.push((c, x, v + 1));
            }
          }
        }
        if let Some(v) = dp2[c][c] {
          q.push((a, a, v + 1));
        }
      } else if b == c {
        for x in 1 ..= N {
          if x < a {
            if let Some(v) = dp2[x][c] {
              q.push((x, a, v + 1));
            }
          } else if x < c {
            if let Some(v) = dp2[x][c] {
              q.push((a, x, v + 1));
            }
          } else {
            if let Some(v) = dp2[c][x] {
              q.push((a, x, v + 1));
            }
          }
        }
        if let Some(v) = dp2[a][a] {
          q.push((c, c, v + 1));
        }
      } else {
        if let Some(v) = dp2[a][a] {
          q.push((b, c, v + 1));
        }
        if let Some(v) = dp2[b][b] {
          q.push((a, c, v + 1));
        }
        if let Some(v) = dp2[c][c] {
          q.push((a, b, v + 1));
        }
      }
      
      q.push((a, b, dp1[0].unwrap()));
      q.push((a, c, dp1[0].unwrap()));
      q.push((b, c, dp1[0].unwrap()));
      
      for x in 1 ..= N {
        for y in &[a,b,c] {
          if let Some(v) = dp1[x] {
            if x < *y {
              q.push((x, *y, v));
            } else {
              q.push((*y, x, v));
            }
          }
        }
      }

      while let Some((a,b,v)) = q.pop() {
        if dp2[a][b].is_none() || dp2[a][b].unwrap() < v {
          let u = dp2[a][b].get_or_insert(v);
          *u = v;
          for i in &[0, a, b] {
            let u = dp1[*i].get_or_insert(0);
            *u = max(*u, v);
          }
        }
      }
    }
    
    let s = S[3 * N - 1];
    println!("{}", base + max(1 + dp2[s][s].unwrap_or(0), dp1[0].unwrap_or(0)));
  }

  
}