using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("3 2");
WillReturn.Add("1 1 1");
WillReturn.Add("2 A");
//001
//000
//000
}
else if (InputPattern == "Input2") {
WillReturn.Add("3 3");
WillReturn.Add("1 1 1");
WillReturn.Add("3 A");
WillReturn.Add("3 B");
//000
//000
//001
}
else if (InputPattern == "Input3") {
WillReturn.Add("4 8");
WillReturn.Add("2 A");
WillReturn.Add("1 4 2");
WillReturn.Add("2 A");
WillReturn.Add("1 2 2");
WillReturn.Add("3 B");
WillReturn.Add("3 B");
WillReturn.Add("3 A");
WillReturn.Add("1 3 1");
//0000
//0000
//0100
//0000
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static int[,] mMatrix90Do;
static int[,] mMatrix270Do;
static int[,] mMatrixRevYoko;
static int[,] mMatrixRevTate;
static decimal mN;
static decimal mGenten;
static void Main()
{
List<string> InputList = GetInputList();
string Result = Solve(InputList);
Console.Write(Result);
}
static int[] GetSplitArr(string pStr)
{
return (pStr == "" ? new string[0] : pStr.Split(' ')).Select(pX => int.Parse(pX)).ToArray();
}
static int UB;
static string Solve(List<string> pInputList)
{
int[] wkArr = GetSplitArr(pInputList[0]);
mN = wkArr[0];
UB = wkArr[0] - 1;
Init();
byte[,] BanArr = new byte[UB + 1, UB + 1];
// 後続の座標変換の行列
int[,] AfterMatrixArr = DeriveUnitMatrix(1);
// クエリを逆から走査
for (int I = pInputList.Count - 1; 1 <= I; I--) {
string[] SplitArr = pInputList[I].Split(' ');
int Type = int.Parse(SplitArr[0]);
if (Type == 1) {
decimal Y = decimal.Parse(SplitArr[1]) - 1;
decimal X = decimal.Parse(SplitArr[2]) - 1;
ExecHenkan1_2(ref X, ref Y);
SetPos(ref X, ref Y, AfterMatrixArr);
ExecHenkan2_1(ref X, ref Y);
BanArr[(int)X, (int)Y]++;
BanArr[(int)X, (int)Y] %= 2;
}
if (Type == 2) {
if (SplitArr[1] == "A") {
// 90度回転
AfterMatrixArr = DeriveMatrixProd(mMatrix90Do, AfterMatrixArr);
}
if (SplitArr[1] == "B") {
// 270度回転
AfterMatrixArr = DeriveMatrixProd(mMatrix270Do, AfterMatrixArr);
}
}
if (Type == 3) {
if (SplitArr[1] == "A") {
// 上下反転
AfterMatrixArr = DeriveMatrixProd(mMatrixRevTate, AfterMatrixArr);
}
if (SplitArr[1] == "B") {
// 左右反転
AfterMatrixArr = DeriveMatrixProd(mMatrixRevYoko, AfterMatrixArr);
}
}
}
// 解を出力
var sb = new System.Text.StringBuilder();
for (int Y = 0; Y <= UB; Y++) {
for (int X = 0; X <= UB; X++) {
sb.Append(BanArr[X, Y]);
}
sb.AppendLine();
}
return sb.ToString();
}
static void Init()
{
mGenten = mN / 2M;
// 行列なので[行,列]という持ち方
mMatrix90Do = new int[,] {{0,-1},
{1,0}};
// 行列なので[行,列]という持ち方
mMatrix270Do = new int[,] {{0,1},
{-1,0}};
// 行列なので[行,列]という持ち方
mMatrixRevYoko = new int[,] {{-1,0},
{0,1}};
// 行列なので[行,列]という持ち方
mMatrixRevTate = new int[,] {{1,0},
{0,-1}};
}
// 座標系1の(X,Y)を座標系2の(X,Y)に変換
static void ExecHenkan1_2(ref decimal pX, ref decimal pY)
{
pX += 0.5M;
pX -= mGenten;
pY += 0.5M;
pY -= mGenten;
pY *= -1;
}
// 座標系2の(X,Y)を座標系1の(X,Y)に変換
static void ExecHenkan2_1(ref decimal pX, ref decimal pY)
{
pX += mGenten;
pX -= 0.5M;
pY *= -1;
pY += mGenten;
pY -= 0.5M;
}
// 座標系2の(X,Y)を後続のクエリ後の座標に変換
static void SetPos(ref decimal pX, ref decimal pY, int[,] pAfterMatrixArr)
{
decimal BeforeX = pX;
decimal BeforeY = pY;
pX = pAfterMatrixArr[0, 0] * BeforeX + pAfterMatrixArr[1, 0] * BeforeY;
pY = pAfterMatrixArr[0, 1] * BeforeX + pAfterMatrixArr[1, 1] * BeforeY;
}
// 単位行列を返す
static int[,] DeriveUnitMatrix(int UB)
{
int[,] WillReturn = new int[UB + 1, UB + 1];
for (int LoopY = 0; LoopY <= UB; LoopY++) {
for (int LoopX = 0; LoopX <= UB; LoopX++) {
if (LoopY == LoopX) {
WillReturn[LoopY, LoopX] = 1;
}
}
}
return WillReturn;
}
// 正方行列2つの積を返す
static int[,] DeriveMatrixProd(int[,] pMatrix1, int[,] pMatrix2)
{
int UB = pMatrix1.GetUpperBound(0);
// 横の値の配列[行]
var YokoArrDict = new Dictionary<int, int[]>();
for (int LoopY = 0; LoopY <= UB; LoopY++) {
var YokoList = new List<int>();
for (int LoopX = 0; LoopX <= UB; LoopX++) {
YokoList.Add(pMatrix1[LoopY, LoopX]);
}
YokoArrDict[LoopY] = YokoList.ToArray();
}
// 縦の値の配列[列]
var TateArrDict = new Dictionary<int, int[]>();
for (int LoopX = 0; LoopX <= UB; LoopX++) {
var TateList = new List<int>();
for (int LoopY = 0; LoopY <= UB; LoopY++) {
TateList.Add(pMatrix2[LoopY, LoopX]);
}
TateArrDict[LoopX] = TateList.ToArray();
}
int[,] MatrixProd = new int[UB + 1, UB + 1];
for (int LoopY = 0; LoopY <= UB; LoopY++) {
for (int LoopX = 0; LoopX <= UB; LoopX++) {
int SumVal = 0;
for (int K = 0; K <= UB; K++) {
SumVal += (YokoArrDict[LoopY][K] * TateArrDict[LoopX][K]);
}
MatrixProd[LoopY, LoopX] = SumVal;
}
}
return MatrixProd;
}
}