#include <bits/stdc++.h>
using namespace std;
inline void read(int &x) {
  int v = 0, f = 1;
  char c = getchar();
  while (!isdigit(c) && c != '-') c = getchar();
  if (c == '-')
    f = -1;
  else
    v = (c & 15);
  while (isdigit(c = getchar())) v = (v << 1) + (v << 3) + (c & 15);
  x = v * f;
}
inline void read(long long &x) {
  long long v = 0ll, f = 1ll;
  char c = getchar();
  while (!isdigit(c) && c != '-') c = getchar();
  if (c == '-')
    f = -1;
  else
    v = (c & 15);
  while (isdigit(c = getchar())) v = (v << 1) + (v << 3) + (c & 15);
  x = v * f;
}
inline void readc(char &x) {
  char c;
  while (((c = getchar()) == ' ') || c == '\n')
    ;
  x = c;
}
const int blk = 256;
int n, m, i, j, cnt, lc[2222222], rc[2222222], ans[65545];
struct ii {
  int x, id;
} a[4105];
int merge(int x, int y) {
  if (!x || !y) return x + y;
  cnt++;
  lc[cnt] = x;
  rc[cnt] = y;
  return cnt;
}
struct block {
  vector<vector<int> > id;
  vector<int> pos;
  void init(int x) {
    id.resize(x);
    pos.resize(x);
    int i;
    for (((i)) = (0); ((i)) <= (((int)(x)) - 1); ((i))++) id[i].resize(x - i);
  }
  void build(int x) {
    if (!x)
      init(0);
    else {
      init(1);
      pos[0] = a[x].id;
      id[0][0] = a[x].id;
    }
  }
  int query(int l, int r) {
    l = lower_bound((pos).begin(), (pos).end(), l) - pos.begin();
    r = upper_bound((pos).begin(), (pos).end(), r) - pos.begin() - 1;
    if (l > r) return 0;
    return id[l][r - l];
  }
  void update(block a, block b) {
    init(a.pos.size() + b.pos.size());
    merge(a.pos.begin(), a.pos.end(), b.pos.begin(), b.pos.end(), pos.begin());
    int i, j;
    for (((i)) = (0); ((i)) <= (((int)(pos.size())) - 1); ((i))++)
      for ((j) = (i); (j) <= (pos.size() - 1); (j)++) {
        id[i][j - i] = merge(a.query(pos[i], pos[j]), b.query(pos[i], pos[j]));
      }
  }
} t[17];
bool cmp(ii x, ii y) { return x.x < y.x; }
block solve(int l, int r) {
  if (l == r) {
    block tmp;
    tmp.build(l);
    return tmp;
  }
  int mid = (l + r) / 2;
  block tmp;
  tmp.update(solve(l, mid), solve(mid + 1, r));
  return tmp;
}
int main() {
  read(n);
  read(m);
  cnt = n;
  for (((i)) = (1); ((i)) <= ((n)); ((i))++) {
    read(a[i].x);
    a[i].id = i;
  }
  sort(a + 1, a + n + 1, cmp);
  for (i = 1; i <= n; i += blk) {
    t[i / blk] = solve(i, min(n, i + blk - 1));
  }
  for (((i)) = (1); ((i)) <= ((m)); ((i))++) {
    int l, r;
    read(l);
    read(r);
    for (j = 1; j <= n; j += blk) {
      ans[i] = merge(ans[i], t[j / blk].query(l, r));
    }
  }
  printf("%d\n", cnt);
  for ((i) = (n + 1); (i) <= (cnt); (i)++) printf("%d %d\n", lc[i], rc[i]);
  for (((i)) = (1); ((i)) <= ((m)); ((i))++) printf("%d ", ans[i]);
  return 0;
}
