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("2");
WillReturn.Add("19");
WillReturn.Add("4 1 1");
WillReturn.Add("4 1 2");
WillReturn.Add("4 2 1");
WillReturn.Add("4 2 2");
WillReturn.Add("3");
WillReturn.Add("4 1 1");
WillReturn.Add("4 1 2");
WillReturn.Add("4 2 1");
WillReturn.Add("4 2 2");
WillReturn.Add("1 1 2");
WillReturn.Add("4 1 1");
WillReturn.Add("4 1 2");
WillReturn.Add("4 2 1");
WillReturn.Add("4 2 2");
WillReturn.Add("2 2 1");
WillReturn.Add("4 1 1");
WillReturn.Add("4 1 2");
WillReturn.Add("4 2 1");
WillReturn.Add("4 2 2");
//0
//1
//2
//3
//0
//2
//1
//3
//1
//3
//0
//2
//3
//1
//2
//0
}
else if (InputPattern == "Input2") {
WillReturn.Add("3");
WillReturn.Add("9");
WillReturn.Add("2 2 3");
WillReturn.Add("3");
WillReturn.Add("1 2 1");
WillReturn.Add("2 3 2");
WillReturn.Add("1 1 3");
WillReturn.Add("3");
WillReturn.Add("4 1 1");
WillReturn.Add("4 2 2");
WillReturn.Add("4 2 3");
//1
//6
//8
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
struct QueryInfoDef
{
internal long Type;
internal long A;
internal long B;
}
static void Main()
{
List<string> InputList = GetInputList();
long[] wkArr = { };
Action<string> SplitAct = pStr =>
wkArr = pStr.Split(' ').Select(pX => long.Parse(pX)).ToArray();
long N = int.Parse(InputList[0]);
long UB = N - 1;
var QueryInfoList = new List<QueryInfoDef>();
foreach (string EachStr in InputList.Skip(2)) {
SplitAct(EachStr);
QueryInfoDef WillAdd;
long Type = wkArr[0];
WillAdd.Type = Type;
if (Type != 3) {
WillAdd.A = wkArr[1] - 1;
WillAdd.B = wkArr[2] - 1;
}
else {
WillAdd.A = -1;
WillAdd.B = -1;
}
QueryInfoList.Add(WillAdd);
}
// 列番号の配列
long[] ColumnIndArr = new long[UB + 1];
// 行番号の配列
long[] RowIndArr = new long[UB + 1];
for (long I = 0; I <= UB; I++) {
ColumnIndArr[I] = I;
RowIndArr[I] = I;
}
// 転置回数
long TentiCnt = 0;
long Cnt = 0;
foreach (QueryInfoDef EachQueryInfo in QueryInfoList) {
long Type = EachQueryInfo.Type;
long A = EachQueryInfo.A;
long B = EachQueryInfo.B;
if (Type == 1) {
if (TentiCnt % 2 == 0) ExecSwap(RowIndArr, A, B);
else ExecSwap(ColumnIndArr, A, B);
}
if (Type == 2) {
if (TentiCnt % 2 == 1) ExecSwap(RowIndArr, A, B);
else ExecSwap(ColumnIndArr, A, B);
}
if (Type == 3) {
TentiCnt++;
}
if (Type == 4) {
if (TentiCnt % 2 == 0) {
long X = ColumnIndArr[B];
long Y = RowIndArr[A];
Console.WriteLine(X + N * Y);
}
else {
long X = RowIndArr[B];
long Y = ColumnIndArr[A];
Console.WriteLine(Y + N * X);
}
}
}
}
// 引数の配列の、2つの添字の値を交換
static void ExecSwap(long[] pArr, long pInd1, long pInd2)
{
long Saved = pArr[pInd1];
pArr[pInd1] = pArr[pInd2];
pArr[pInd2] = Saved;
}
}