Problem:
Problem B: Cubes Without Holes

There is a cube which consists of n × n × n small cubes. Small cubes have marks on their surfaces. An example where n = 4 is shown in the following figure.

Then,
次に、上図（右）に示すように、印のついた表面から、反対の面まで水平または垂直に貫通する穴をあける。

あなたの仕事は、n と 印の位置を読み込み、穴の空いていない小さい立方体の個数を数えるプログラムを作成することである。

Input

入力はいくつかのデータセットからなる。各データセットは以下の形式で与えられる：

n h
c1 a1 b1
c2 a2 b2
.
.
.
ch ah bh

h は印の数を示す整数である。これに続く h 行によって h 個の印の位置が入力される。印の位置を指定するために下図に示す座標軸を用いることにする。(x, y, z) = (1, 1, 1) が左下奥の立方体、(x, y, z) = (n, n, n) が右上手前の立方体を示す。

ci は i 番目の印がつけられている平面を示す文字列である。ci は "xy" 、"xz"、 "yz"　のいづれかであり、それぞれ i 番目の印が xy 平面、xz 平面、 yz 平面上にあることを示す。

ai, bi　は　ci で示された平面上の座標を示す。 xy 平面、xz 平面、yz 平面のとき、ai, bi はそれぞれ平面の座標 (x, y)、(x, z)、(y, z) を示す。例えば、上図において、印 A, B, C の ci, ai, bi の値はそれぞれ、"xy 4 4", "xz 1 2", "yz 2 3" となる。

n, h がともに 0 のとき、入力の終わりを示す。

n ≤ 500, h ≤ 200 と仮定してよい。

Output

各データセットに対して、穴の空いていない立方体の数を１行に出力せよ。

Sample Input

4 3
xy 4 4
xz 1 2
yz 2 3
4 5
xy 1 1
xy 3 3
xz 3 3
yz 2 1
yz 3 3
0 0

Output for the Sample Input

52
46

Solution in JAVA (judge verdict: Wrong Answer)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String line = "";

		short n, h;
		short[][] holes;
		int intersect;

		while ((line = br.readLine()) != null && !line.isEmpty()) {

			n = Short.parseShort(line.substring(0, line.indexOf(' ')));
			h = Short.parseShort(line.substring(line.indexOf(' ') + 1));
			if ((n | h) == 0) {
				break;
			}
			holes = new short[h][4];

			StringTokenizer st;
			for (int i = 0; i < h; i++) {
				st = new StringTokenizer(br.readLine());
				String plane = st.nextToken();
				if (plane.equals("xy")) {
					holes[i][0] = Short.parseShort(st.nextToken());
					holes[i][1] = Short.parseShort(st.nextToken());
					holes[i][3] = 1;
				} else if (plane.equals("xz")) {
					holes[i][0] = Short.parseShort(st.nextToken());
					holes[i][2] = Short.parseShort(st.nextToken());
					holes[i][3] = 2;
				} else {
					holes[i][1] = Short.parseShort(st.nextToken());
					holes[i][2] = Short.parseShort(st.nextToken());
					holes[i][3] = 4;
				}
			}
			// 交点判定
			intersect = 0;
			for (int i = 0; i < h - 2; i++) {
				for (int j = 1; j < h - 1; j++) {
					for (int k = 2; k < h; k++) {
						//
						if (i < j && j < k) {
							short p1, p2, p3;
							p1 = holes[i][3];
							p2 = holes[j][3];
							p3 = holes[k][3];
							if ((p1 | p2) == p3) {
								continue;
							} else {
								boolean b1, b2, b3;
								b1 = cross(holes[i], holes[j]);
								b2 = cross(holes[j], holes[k]);
								b3 = cross(holes[k], holes[i]);
								// 3線交差
								if (b1 & b2 & b3) {
									intersect++;
								} else {
									if (b1)
										intersect++;
									if (b2)
										intersect++;
									if (b3)
										intersect++;
								}
							}
						}
						//
					}
				}
			}
			// 穴の開いていない立方体の数
			System.out.println((int) Math.pow(n, 3) - n * h + intersect);
		}
	}

	static boolean cross(short[] p1, short[] p2) {
		boolean b = false;
		for (int p = 0; p < 3; p++) {
			b = true;
			b &= (p1[p] == p2[p]);
			b &= (p2[(p + 1) % 3] == 0);
			b &= (p2[(p + 2) % 3] == 0);
			if (b)
				break;
		}
		return b;
	}
}