#include<bits/stdc++.h>
using namespace std;
const int N = 105;
int n, a[N][N], b[N][N];
typedef vector<pair<int,int>> instructions;
bool cmp(const instructions& a, const instructions& b) {
return a.size() < b.size();
}
int c[N][N];
bitset<N> column_c[N], column_b[N];
int id_b[N], id_c[N];
vector<int> group_c[N], group_b[N];
bool solve(instructions& res) {
//transform table c to table b
res.size();
for (int j = 1; j <= n; j++) {
column_c[j].reset();
column_b[j].reset();
for (int i = 1; i <= n; i++)
column_c[j].set(i, c[i][j]),
column_b[j].set(i, b[i][j]);
}
for (int i = 1; i <= n; i++) {
group_b[i].clear();
group_c[i].clear();
group_b[i].push_back(i);
group_c[i].push_back(i);
id_b[i] = i, id_c[i] = i;
}
for (int i = 1; i <= n; i++) {
if (id_b[i] < i) continue;
for (int j = i+1; j <= n; j++)
if (column_b[j] == column_b[i])
id_b[j] = i, group_b[i].push_back(j);
}
for (int i = 1; i <= n; i++) {
if (id_c[i] < i) continue;
for (int j = i+1; j <= n; j++)
if (column_c[j] == column_c[i])
id_c[j] = i, group_c[i].push_back(j);
}
int perm[N];
for (int i = 1; i <= n; i++) {
if (id_c[i] < i) continue;
bool found = false;
for (int j = 1; j <= n; j++)
if (id_b[j] == j and column_c[i] == column_b[j]) {
found = true;
if (group_c[i].size() != group_b[j].size()) return false;
for (int k = 0; k < (int) group_c[i].size(); k++)
perm[group_c[i][k]] = group_b[j][k];
}
if (!found) return false;
}
for (int i = 1; i <= n; i++) {
int j = -1;
for (int k = i; k <= n; k++)
if (perm[k] == i) { j = k; break; }
for (int k = j-1; k >= i; k--) {
swap(perm[k], perm[k+1]);
res.emplace_back(1,k);
}
}
return true;
}
void subtask4() {
vector<instructions> solutions;
for (int col_c : {n,n-1}) {
for (int col_b = 1; col_b <= n; col_b++) {
instructions cur;
int cnt_diff = 0, diff = 0, pos = 0;
for (int i = 1; i <= n; i++) {
bool flip = a[i][col_c] != b[i][col_b];
if (flip) cur.emplace_back(2,i);
for (int j = 1; j <= n; j++)
c[i][j] = flip ? 1-a[i][j] : a[i][j];
int cnt_c = count(c[i]+1, c[i]+1+n, 1);
int cnt_b = count(b[i]+1, b[i]+1+n, 1);
if (cnt_c != cnt_b) pos = i;
cnt_diff += abs(cnt_b - cnt_c);
diff += cnt_c - cnt_b;
}
if (cnt_diff > 1) continue;
if (cnt_diff == 1) {
int bit = (diff > 0) ? 1 : 0;
for (int j = 1; j <= n; j++)
if (j != col_c and c[pos][j] == bit) {
instructions nxt = cur;
c[pos][j] ^= 1;
if (solve(nxt)) solutions.push_back(nxt);
c[pos][j] ^= 1;
}
} else
if (solve(cur)) solutions.push_back(cur);
}
}
if (solutions.empty())
{ puts("-1"); return ; }
auto ans = *min_element(begin(solutions), end(solutions), cmp);
printf("%d\n", (int) ans.size());
for (auto cmd : ans)
printf("%d %d\n", cmd.first, cmd.second);
}
int main()
{
#define task "board"
if (fopen(task".inp", "r")) {
freopen(task".inp", "r", stdin);
freopen(task".out", "w", stdout);
}
scanf("%d", &n);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) scanf("%d", &a[i][j]);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) scanf("%d", &b[i][j]);
subtask4();
}