#include <bits/stdc++.h>
using namespace std;
int block;
struct Query {
  int l, r, p;
  Query(int _l, int _r, int _p) {
    l = _l;
    r = _r;
    p = _p;
  }
  bool operator<(const Query& q) const { return r < q.r; }
};
int n, m, u, v, a[50005], s[1000005], res[5005];
vector<Query> query[305];
struct Trie {
  struct node {
    int mn, mx;
    int nxt[2];
    node() {
      mn = 1e9;
      mx = 0;
      nxt[0] = nxt[1] = -1;
    }
  };
  vector<node> trie;
  Trie() { trie.push_back(node()); }
  void add(int x) {
    int sx = s[x], cur = 0;
    for (int i = 20; i >= 0; --i) {
      bool t = sx >> i & 1;
      if (trie[cur].nxt[t] == -1) {
        trie[cur].nxt[t] = trie.size();
        trie.push_back(node());
      }
      cur = trie[cur].nxt[t];
      trie[cur].mn = min(trie[cur].mn, x);
      trie[cur].mx = max(trie[cur].mx, x);
    }
  }
  int get(int x, bool type) {
    int res = 0, sx = s[x], cur = 0;
    for (int i = 20; i >= 0; --i) {
      bool t = sx >> i & 1;
      int nxt1 = trie[cur].nxt[1 - t];
      int nxt0 = trie[cur].nxt[t];
      if (type) {
        if (nxt1 != -1 && trie[nxt1].mx > x) {
          res += 1 << i;
          cur = nxt1;
        } else if (nxt0 != -1 && trie[nxt0].mx > x) {
          cur = nxt0;
        }
      } else {
        if (nxt1 != -1 && trie[nxt1].mn < x) {
          res += 1 << i;
          cur = nxt1;
        } else if (nxt0 != -1 && trie[nxt0].mn < x) {
          cur = nxt0;
        }
      }
    }
    return res;
  }
};
int main() {
  ios::sync_with_stdio(false);
  for (int i = 1; i <= 1000000; ++i) s[i] = s[i - 1] ^ i;
  cin >> n >> m;
  int block = sqrt(n);
  for (int i = 1; i <= n; ++i) cin >> a[i];
  for (int i = 1; i <= m; ++i) {
    cin >> u >> v;
    query[(u - 1) / block].push_back(Query(u, v, i));
  }
  for (int i = 0; i <= (n - 1) / block; ++i) {
    sort(query[i].begin(), query[i].end());
    int R, L;
    L = R = (i + 1) * block;
    int rconst = 0;
    Trie Left, Right;
    for (int j = 0; j < query[i].size(); ++j) {
      int l = query[i][j].l, r = query[i][j].r, p = query[i][j].p;
      while (r > R) {
        R++;
        Left.add(a[R] - 1);
        Right.add(a[R]);
        rconst = max(rconst, max(Left.get(a[R], 0), Right.get(a[R] - 1, 1)));
      }
      Trie TmpLeft, TmpRight;
      for (int k = l; k <= min(r, L); ++k) {
        TmpLeft.add(a[k] - 1);
        TmpRight.add(a[k]);
        res[p] =
            max(res[p], max(TmpLeft.get(a[k], 0), TmpRight.get(a[k] - 1, 1)));
        if (r == R && R > L) {
          res[p] = max(res[p], max(Left.get(a[k], 0), Right.get(a[k] - 1, 1)));
        }
      }
      if (r == R && R > l) res[p] = max(res[p], rconst);
    }
  }
  for (int i = 1; i <= m; ++i) cout << res[i] << '\n';
}
