1 #include 2 #include 3 #include 4 #include 5 #define MAXM 80 6 #define MAXN 100000 7 #define INF 0x7FFFFFFF 8 using namespace std; 9 int L[MAXN], R[MAXN], U[MAXN], D[MAXN]; 10 int S[MAXN], H[MAXN], C[MAXN]; 11 int a[MAXM][MAXM], size, ans; 12 bool exist[MAXM], vis[MAXM]; 13 vector p[MAXM]; 14 void Init(int n, int m) { 15 int i; 16 for (i = 0; i <= m; i++) { 17 L[i + 1] = i; 18 R[i] = i + 1; 19 U[i] = D[i] = i; 20 S[i] = 0; 21 } 22 R[m] = 0; 23 size = m + 1; 24 m = n * (n + 1) << 1; 25 for (i = 0; i <= m; i++) 26 H[i] = -1; 27 } 28 inline void Link(int r, int c) { 29 D[size] = D[c]; 30 U[size] = c; 31 U[D[c]] = size; 32 D[c] = size; 33 if (H[r] < 0) 34 H[r] = L[size] = R[size] = size; 35 else { 36 L[size] = H[r]; 37 R[size] = R[H[r]]; 38 L[R[H[r]]] = size; 39 R[H[r]] = size; 40 } 41 S[c]++; 42 C[size++] = c; 43 } 44 int A() { 45 int i, j, k, res; 46 memset(vis, false, sizeof(vis)); 47 for (res = 0, i = R[0]; i; i = R[i]) { 48 if (vis[i]) 49 continue; 50 res++; 51 for (j = D[i]; j != i; j = D[j]) { 52 for (k = R[j]; k != j; k = R[k]) 53 vis[C[k]] = true; 54 } 55 } 56 return res; 57 } 58 void Remove(int c) { 59 int i; 60 for (i = D[c]; i != c; i = D[i]) { 61 L[R[i]] = L[i]; 62 R[L[i]] = R[i]; 63 } 64 } 65 void Resume(int c) { 66 int i; 67 for (i = D[c]; i != c; i = D[i]) 68 L[R[i]] = R[L[i]] = i; 69 } 70 void Dance(int now) { 71 if (R[0] == 0) 72 ans = min(ans, now); 73 else if (now + A() < ans) { 74 int i, j, temp, c; 75 for (temp = INF,i = R[0]; i; i = R[i]) { 76 if (temp > S[i]) { 77 temp = S[i]; 78 c = i; 79 } 80 } 81 for (i = D[c]; i != c; i = D[i]) { 82 Remove(i); 83 for (j = R[i]; j != i; j = R[j]) 84 Remove(j); 85 Dance(now + 1); 86 for (j = L[i]; j != i; j = L[j]) 87 Resume(j); 88 Resume(i); 89 } 90 } 91 } 92 void Connect(int len, int row, int col, int r) { 93 int i; 94 for (i = row; i <= row + len; i++) { 95 if (a[i][col] && exist[a[i][col]]) 96 p[a[i][col]].push_back(r); 97 if (a[i][col + len] && exist[a[i][col + len]]) 98 p[a[i][col + len]].push_back(r); 99 }100 for (i = col + 1; i < col + len; i++) {101 if (a[row][i] && exist[a[row][i]])102 p[a[row][i]].push_back(r);103 if (a[row + len][i] && exist[a[row + len][i]])104 p[a[row + len][i]].push_back(r);105 }106 }107 bool OK(int len, int row, int col) {108 int i;109 for (i = row; i <= row + len; i++) {110 if (a[i][col] && !exist[a[i][col]])111 return false;112 if (a[i][col + len] && !exist[a[i][col + len]])113 return false;114 }115 for (i = col + 1; i < col + len; i++) {116 if (a[row][i] && !exist[a[row][i]])117 return false;118 if (a[row + len][i] && !exist[a[row + len][i]])119 return false;120 }121 return true;122 }123 int Build(int n) {124 int i, j, k, r;125 memset(a, 0, sizeof(a));126 for (i = 0; i < MAXM; i++)127 p[i].clear();128 for (i = k = r = 0; i < n; i++) {129 if (i & 1) {130 for (j = 0; j < n; j += 2)131 a[i][j] = ++k;132 } else {133 for (j = 1; j < n; j += 2)134 a[i][j] = ++k;135 }136 }137 for (i = 2; i < n; i += 2) {138 for (j = 0; j <= n - i; j += 2) {139 for (k = 0; k <= n - i; k += 2) {140 if (OK(i, j, k)) {141 r++;142 Connect(i, j, k, r);143 }144 }145 }146 }147 return r;148 }149 int main() {150 int T, n, m, i, j;151 scanf("%d", &T);152 while (T--) {153 scanf("%d%d", &n, &m);154 memset(exist, true, sizeof(exist));155 for (i = 0; i < m; i++) {156 scanf("%d", &j);157 exist[j] = false;158 }159 i = Build((n << 1) + 1);160 Init(n, i);161 for (i = 1; i <= n * (n + 1) << 1; i++) {162 for (j = 0; j < p[i].size(); j++)163 Link(i, p[i][j]);164 }165 ans = INF;166 Dance(0);167 printf("%d\n", ans);168 }169 return 0;170 }