#include <bits/stdc++.h>

#define INF 1000000005
#define INFL 1000000000000000005ll
#define EPS 1e-6
#define pb push_back
#define pause system("pause")
#define exit exit(0)
#define endl '\n'

using namespace std;
using ull = unsigned long long;
using ll = long long;

typedef pair<ll, ll> pii;
const int N = 405, MOD = 998244353;

mt19937 rng(time(NULL));

int n, m, a[N][N], fa[N * N], pre[N * N], V;
set<pii> ed;
vector<vector<int>> cyc;
pair<pii, pii> dat[N * N];
set<int> g[N * N];
vector<pii> ic[N];
vector<pii> ans;

inline void del(int u, int v) {
	if (!ed.count({ u, v })) {
		pause;
	}
	
	ed.erase({ u, v });
}

inline void add(int u, int v) {
	ed.insert({ u, v });
}

int get(int i) {
	return fa[i] == i ? i : fa[i] = get(fa[i]);
}

int mrg(int i, int j, int u, int v) {
	if (rng() & 1) {
		swap(i, j), swap(u, v);
	}

	del(pre[u], u), del(pre[v], v);
	add(pre[u], v), add(pre[v], u);
	swap(pre[u], pre[v]);
	fa[j] = i;
	return i;
}

inline void pm(int u1, int u2) {
	int i = dat[u1].second.first, j = dat[u1].second.second;
	int k = dat[u2].second.first, l = dat[u2].second.second;
	assert(a[k][l] == 0);
	a[k][l] = a[i][j], a[i][j] = 0;
	if ((i - 1) * m + j < 1) {
		pause;
	}
	ans.pb({ (i - 1) * m + j, (k - 1) * m + l });
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);

	cin >> n >> m;
	vector<int> np(n * m);
	for (int i = 0; i < n * m; ++i) {
		np[i] = (i / n) + 1;
	}

	shuffle(np.begin(), np.end(), rng);

	int cur = 0;
	set<pair<pii, int>> q;
	for (int i = 1; i <= n; ++i) {
		bitset<405> b, bb;
		for (int j = 1; j <= m; ++j) {
			//cin >> a[i][j];
			a[i][j] = np[(i - 1) * m + j - 1];
			b.set(a[i][j]);
		}

		int mex = 1;
		for (int j = 1; j <= m; ++j) {
			if (bb.test(a[i][j])) {
				while (b.test(mex)) ++mex;
				dat[++cur] = { { a[i][j], mex }, { i, j } };
				q.insert({ { a[i][j], mex }, cur });
				++mex;
			} else {
				bb.set(a[i][j]);
			}
		}
	}

	V = n * m + 1;
	if (cur == 0) {
		cout << 0 << endl;
		return 0;
	}

	while (!q.empty()) {
		auto p = *q.begin();
		q.erase(q.begin());
		vector<int> c;
		c.pb(p.second);
		int V_val = p.first.first;
		while (p.first.second != V_val) {
			auto pp = q.lower_bound({ { p.first.second, -INF }, -INF });
			assert(pp->first.first == p.first.second);
			c.pb(pp->second);
			p = *pp;
			q.erase(pp);
		}

		cyc.pb(c);
		int ff = (int)cyc.size() - 1;
		fa[ff] = ff;
		for (auto u : c) {
			ic[dat[u].first.first].pb({ ff, u });
		}

		int sz = c.size();
		pre[c[0]] = c[sz - 1];
		ed.insert({ c[sz - 1], c[0] });
		for (int i = 1; i < sz; ++i) {
			pre[c[i]] = c[i - 1];
			ed.insert({ c[i - 1], c[i] });
		}
	}

	for (int i = 1; i < N; ++i) {
		if (ic[i].empty()) {
			continue;
		}

		set<int> qq;
		map<int, int> ver;
		for (auto s : ic[i]) {
			qq.insert(get(s.first));
			ver[get(s.first)] = s.second;
		}

		if (qq.size() != 1) {
			int cur = *qq.begin();
			qq.erase(qq.begin());
			for (auto x : qq) {
				cur = mrg(cur, x, ver[cur], ver[x]);
			}
		}
	}

	for (auto x : ed) {
		pre[x.second] = x.first;
	}

	cyc.clear();
	vector<char> vis(cur + 1);
	for (int i = 1; i <= cur; ++i) {
		if (!vis[i]) {
			int u = i;
			vector<int> c;
			while (!vis[u]) {
				c.pb(u), vis[u] = 1, u = pre[u];
			}

			reverse(c.begin(), c.end());
			cyc.pb(c);
		}
	}

	dat[cur + 1] = { {}, { n + 1, 1 } };
	for (auto c : cyc) {
		int sz = c.size();
		pm(c[0], cur + 1);
		for (int i = 1; i < sz; ++i) {
			pm(c[i], c[i - 1]);
		}
		pm(cur + 1, c[sz - 1]);
	}

	for (int i = 1; i <= n; ++i) {
		set<int> q;
		for (int j = 1; j <= m; ++j) {
			q.insert(a[i][j]);
		}

		assert(q.size() == m);
	}

	cout << ans.size() << endl;
	for (auto x : ans) {
		cout << x.first << ' ' << x.second << endl;
	}
	//main();
	//pause;
	return 0;
}
