Go: package main

import "fmt"

func main() {
	//部屋を生成
	var H int

	fmt.Scan(&H)
	room := [][4]bool{}

	for i := 0; i < H; i++ {
		room = append(room, [4]bool{})
	}

	//荷物のおけない区画を設定
	var N int
	fmt.Scan(&N)
	for i := 0; i < N; i++ {
		var x, y int
		fmt.Scan(&x, &y)
		room[y][x] = true //ものがある状態を真とする
	}
	//荷物を配置
	var count int
	for j := 0; j < H-1; j++ {
		for i := 0; i < 3; i++ {

			if !room[j][i] && !room[j+1][i] && !room[j][i+1] && !room[j+1][i+1] {
				//if i!=0&&i!=2&&j!=H-3{
				//	if !room[j+1][i-1]&&!room[j+1][i+2]{
				//		if !room[j+2][0]&&!room[j+2][1]&&!room[j+2][2]&&!room[j+2][3]{
				//			break
				//		}
				//	}
				//}
				room[j][i] = true
				room[j+1][i] = true
				room[j][i+1] = true
				room[j+1][i+1] = true
				count++
			}
		}
	}
	//for _,v:=range room{
	//	for _,v2:=range v{
	//		if v2{
	//			fmt.Print("x")
	//
	//		}else{
	//			fmt.Print("o")
	//		}
	//
	//	}
	//	fmt.Println()
	//}
	fmt.Println(count)
}

C++: #include<bits/stdc++.h>
using namespace std;
using ll = long long;

// #undef DEBUG
// #define DEBUG
/// {{{ DEBUG --- ///
#ifdef DEBUG
template <typename T> ostream &operator<<(ostream &o, const vector<T> &v) { o << "{"; for(size_t i = 0; i < v.size(); i++) o << v[i] << (i + 1 != v.size() ? ", " : ""); o << "}"; return o; }
#ifdef USE_COUT
#define dump(...) [&](){auto __debug_tap=make_tuple(__VA_ARGS__);cout<<"["<<__LINE__<< "] "<<#__VA_ARGS__<<" = "<<__debug_tap<<"\n";}()
#else
#define dump(...) [&](){auto __debug_tap=make_tuple(__VA_ARGS__);cerr<<"["<<__LINE__<< "] "<<#__VA_ARGS__<<" = "<<__debug_tap<<"\n";}()
#endif
template<class T> inline void dump2D(T &d, size_t sizey, size_t sizex) { ostream&o=
#ifdef USE_COUT
  cout;
#else
  cerr;
#endif
  for(size_t i = 0; i < sizey; i++) { for(size_t j = 0; j < sizex; j++) o << d[i][j] << " "; o << endl; }
}
#else
template <typename T> ostream &operator<<(ostream &o, const vector<T> &v) { for(size_t i = 0; i < v.size(); i++) o << v[i] << (i + 1 != v.size() ? " " : ""); return o; }
#define dump(...) (42)
#define dump2D(...) (42)
#endif
template<int n, class...T> typename enable_if<(n>=sizeof...(T))>::type _ot(ostream &, tuple<T...> const &){}
template<int n, class...T> typename enable_if<(n< sizeof...(T))>::type _ot(ostream & os, tuple<T...> const & t){ os << (n==0?"":", ") << get<n>(t); _ot<n+1>(os, t); }
template<class...T> ostream & operator<<(ostream &o, tuple<T...> const &t){ o << "("; _ot<0>(o, t); o << ")"; return o; }
template<class T, class U> ostream & operator<<(ostream &o, pair<T, U> const &p) { o << "(" << p.first << ", " << p.second << ")"; return o; }
/// }}}--- ///


int f[4][11234];
int h;
int n;

int dp[11234][1 << 3];

int check(int y, int x) {
  for(int i = y; i <= y + 1; i++) for(int j = x; j <= x + 1; j++) {
    if(f[j][i]) return 0;
  }
  return 1;
}

int main() {
  std::ios::sync_with_stdio(false), std::cin.tie(0);
  cin >> h;
  cin >> n;
  for(int i = 0; i < n; i++) {
    int x, y;
    cin >> x >> y;
    f[x][y] = 1;
  }
  
  int ans = 0;
  {
    int y = 0;
    for(int i = 0; i < (1 << 3); i++) {
      int cnt = 0, no = 0;
      for(int ii = 0; ii < 3; ii++) if(i & (1 << ii)) {
        if(!check(y, ii)) no = 1;
        cnt++;
      }
      if(__builtin_popcount(i) >= 2) if(i != 5) no = 1; 
      if(no) continue;
      dp[y][i] = cnt;
      dump(y, i, cnt);
      ans = max(ans, dp[y][i]);
    }
  }

  for(int y = 0; y < h - 2; y++) {
    // yでの置き方
    for(int i = 0; i < (1 << 3); i++) {
      int no = 0;
      for(int ii = 0; ii < 3; ii++) if(i & (1 << ii)) {
        if(!check(y, ii)) no = 1;
      }
      if(__builtin_popcount(i) >= 2) if(i != 5) no = 1; 
      if(no) continue;
      // y + 1での置き方
      for(int j = 0; j < (1 << 3); j++) {
        int cnt = 0, no = 0;
        for(int ii = 0; ii < 3; ii++) if(j & (1 << ii)) {
          if(!check(y + 1, ii)) no = 1;
          cnt++;
        }
        if(__builtin_popcount(j) >= 2) if(j != 5) no = 1; 
        for(int ii = 0; ii < 3; ii++) for(int jj = 0; jj < 3; jj++) 
          if(i&(1 << ii)) if(j &(1<<jj)) {
            if(abs(ii - jj) <= 1) no = 1;
          }
        if(no) continue;
        dp[y+1][j] = max(dp[y+1][j], dp[y][i] + cnt);
        ans = max(ans, dp[y + 1][j]);
      }
    }
  }
  cout << ans << endl;
  return 0;
}