#include <bits/stdc++.h>
using namespace std;
class DSU {
 private:
  vector<int> pre;

 public:
  DSU(int n) {
    for (int i = 0; i < n; ++i) pre.push_back(i);
  }
  void MakeSet(int n) { pre[n] = n; }
  int FindSet(int n) {
    if (n == pre[n])
      return n;
    else
      return pre[n] = FindSet(pre[n]);
  }
  void unite(int a, int b) {
    if (pre[a] != a) a = FindSet(a);
    if (pre[b] != b) b = FindSet(b);
    if (rand() % 2) {
      pre[b] = a;
    } else {
      pre[a] = b;
    }
  }
  void AddToSet(vector<int>::iterator begin, vector<int>::iterator end,
                int set) {
    for (vector<int>::iterator i = begin; i != end; ++i) {
      pre[*i] = set;
    }
  }
  void AddToSet(int n, int set) { pre[n] = set; }
  void clear() { pre.clear(); }
  void assign(int n) {
    pre.clear();
    for (int i = 0; i < n; ++i) pre.push_back(i);
  }
};
class MyVecInt : public vector<int> {
 private:
  int a;

 public:
  MyVecInt() {}
  MyVecInt(int n) { this->assign(n, 0); }
  void assign_(int l, int d, int r) {
    for (int i = l; i < r; i += d) {
      this->push_back(i);
    }
  }
  void get(int n) {
    for (int i = 0; i < n; ++i) {
      scanf("%d", &a);
      this->push_back(a);
    }
  }
  void print(string a, int q = 0, int w = -1) {
    if (w == -1 || w > this->size()) w = this->size();
    for (int i = q; i < w; ++i) {
      cout << this->at(i) << a;
    }
  }
  void srt() { sort(this->begin(), this->end()); }
  void rsrt() { sort(this->rbegin(), this->rend()); }
  void operator+(MyVecInt buf) {
    this->insert(this->end(), buf.begin(), buf.end());
  }
  void operator+(int n) { this->push_back(n); }
  void pb(int n) { this->push_back(n); }
  bool replac(int n, int m) {
    vector<int>::iterator i = find(this->begin(), this->end(), n);
    if (i != this->end()) {
      *i = m;
      return 1;
    }
    return 0;
  }
  void revers() { reverse(this->begin(), this->end()); }
};
int in() {
  int a;
  scanf("%d", &a);
  return a;
}
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
int lcm(int a, int b) { return a / gcd(a, b) * b; }
int INF = 1000000;
void snikeAround(int ver, vector<int> &dis, vector<vector<int> > &G,
                 vector<bool> &block, vector<int> &p) {
  for (int i = 0; i < dis.size(); ++i) {
    if (G[ver][i] != -1) {
      if (dis[i] > dis[ver] + G[ver][i]) {
        dis[i] = dis[ver] + G[ver][i];
        p[i] = ver;
      }
    }
  }
  block[ver] = 1;
}
int getNext(vector<int> &dis, vector<bool> &block) {
  int m = INF, res = -1;
  for (int i = 0; i < dis.size(); ++i) {
    if (!block[i] && dis[i] < m) {
      m = dis[i];
      res = i;
    }
  }
  return res;
}
void dfs(int v, vector<vector<int> > &g, vector<bool> &u) {
  u[v] = true;
  for (int i = 0; i < g[v].size(); ++i) {
    if (!u[i] && g[v][i]) {
      dfs(i, g, u);
    }
  }
}
void bfs(vector<vector<int> > &g, vector<bool> &u, vector<int> &d,
         queue<int> &f) {
  int v = f.front();
  f.pop();
  for (int i = 0; i < g[v].size(); ++i) {
    if (!u[i] && g[v][i]) {
      u[i] = true;
      d[i] = d[v] + 1;
      f.push(i);
    }
  }
}
void TopSort(vector<bool> &u, vector<int> &res, vector<vector<int> > &g) {
  for (int i = 0; i < u.size(); ++i) {
    if (!u[i]) {
      dfs(i, g, u);
    }
  }
}
bool kruskal(vector<pair<int, pair<int, int> > > &g, DSU &t, int &cost,
             vector<bool> &u) {
  bool res = 0;
  for (int i = 0; i < g.size(); ++i) {
    if (t.FindSet(g[i].second.second) != t.FindSet(g[i].second.first)) {
      u[i] = 1;
      cost += g[i].first;
      res = 1;
      t.unite(g[i].second.second, g[i].second.first);
    }
  }
  return res;
}
void bfs_(int n, int m, vector<bool> &u, vector<int> &d, queue<int> &f) {
  int v = f.front();
  f.pop();
  int y = v / m, x = v % m;
  if (y && !u[v - m]) {
    f.push(v - m);
    d[v - m] = d[v] + 1;
    u[v - m] = 1;
  }
  if (x && !u[v - 1]) {
    f.push(v - 1);
    d[v - 1] = d[v] + 1;
    u[v - 1] = 1;
  }
  if (y < n - 1 && !u[v + m]) {
    f.push(v + m);
    d[v + m] = d[v] + 1;
    u[v + m] = 1;
  }
  if (x < m - 1 && !u[v + 1]) {
    f.push(v + 1);
    d[v + 1] = d[v] + 1;
    u[v + 1] = 1;
  }
}
int main() {
  int m = in(), n = in();
  if (m == 1 && n == 2) {
    cout << "0\n1 1\n1 2\n1 1\n";
    return 0;
  }
  if (n == 1 && m == 1) {
    cout << "0\n1 1\n1 1\n";
    return 0;
  }
  if (m == 2 && n == 1) {
    cout << "0\n1 1\n2 1\n1 1\n";
    return 0;
  }
  if (n % 2 == 0 && m != 1) {
    cout << "0" << endl;
    for (int i = 1; i <= n; ++i) cout << "1 " << i << endl;
    bool h = 0;
    for (int i = n; i >= 1; --i) {
      if (!h) {
        for (int j = 2; j <= m; ++j) {
          cout << j << " " << i << endl;
        }
        h = 1;
      } else {
        h = 0;
        for (int j = m; j >= 2; --j) {
          cout << j << " " << i << endl;
        }
      }
    }
    cout << "1 1" << endl;
    return 0;
  }
  if (m % 2 == 0 && n != 1) {
    cout << "0" << endl;
    for (int i = 1; i <= n; ++i) cout << "1 " << i << endl;
    for (int i = 2; i <= m; ++i) cout << i << " " << n << endl;
    bool l = 0;
    for (int i = m; i >= 2; --i) {
      if (!l) {
        for (int j = n - 1; j >= 1; --j) {
          cout << i << " " << j << endl;
        }
        l = 1;
      } else {
        l = 0;
        for (int j = 1; j < n; ++j) {
          cout << i << " " << j << endl;
        }
      }
    }
    cout << "1 1" << endl;
    return 0;
  }
  cout << "1\n" << m << " " << n << " 1 1\n";
  bool l = 0;
  for (int i = 1; i <= m; ++i) {
    if (!l) {
      for (int j = 1; j <= n; ++j) {
        cout << i << " " << j << endl;
      }
      l = 1;
    } else {
      l = 0;
      for (int j = n; j >= 1; --j) {
        cout << i << " " << j << endl;
      }
    }
  }
  cout << "1 1" << endl;
  return 0;
}
