#include <bits/stdc++.h>
using namespace std;
const int MAX = 1000000;
const int MAX_N = 50000;
const int oo = 1e9;
const int LOGN = 20;
const int Z = 230;
int f[MAX + 1], n, m, a[MAX_N], ans[MAX_N];
struct node {
  int nxt[2], val;
  multiset<int> mst;
  node() {
    memset(nxt, -1, sizeof nxt);
    val = oo;
  }
};
struct query {
  int l, r, idx;
  query(int _l, int _r, int _idx) { l = _l, r = _r, idx = _idx; }
  bool operator<(const query &rhs) const { return r < rhs.r; }
};
vector<query> q[Z];
struct honey {
  vector<node> trie;
  int ty;
  honey(int _ty) { ty = _ty; }
  void insert(int u, int depth, int first, int ax, bool add) {
    if (!trie.size()) trie.push_back(node());
    if (depth == -1) {
      if (add)
        trie[u].mst.insert(ax);
      else
        trie[u].mst.erase(trie[u].mst.find(ax));
      if (ty == 0) {
        trie[u].val = trie[u].mst.size() ? *trie[u].mst.begin() : oo;
      } else {
        trie[u].val = trie[u].mst.size() ? *--trie[u].mst.end() : -oo;
      }
      return;
    }
    bool bt = (first >> depth) & 1;
    if (trie[u].nxt[bt] == -1) {
      trie[u].nxt[bt] = trie.size();
      trie.push_back(node());
    }
    insert(trie[u].nxt[bt], depth - 1, first, ax, add);
    trie[u].val = (!ty ? oo : -oo);
    if (trie[u].nxt[bt] != -1) trie[u].val = trie[trie[u].nxt[bt]].val;
    if (trie[u].nxt[bt ^ 1] != -1) {
      if (!ty)
        trie[u].val = min(trie[u].val, trie[trie[u].nxt[bt ^ 1]].val);
      else
        trie[u].val = max(trie[u].val, trie[trie[u].nxt[bt ^ 1]].val);
    }
  }
  int search(int u, int depth, int first, int ax) {
    if (depth == -1 || u == -1 ||
        (ty == 0 ? trie[u].val > ax : trie[u].val < ax))
      return 0;
    bool bt = (first >> depth) & 1;
    if (trie[u].nxt[bt ^ 1] != -1 &&
        (ty == 0 ? trie[trie[u].nxt[bt ^ 1]].val <= ax
                 : trie[trie[u].nxt[bt ^ 1]].val >= ax))
      return (1 << depth) + search(trie[u].nxt[bt ^ 1], depth - 1, first, ax);
    return search(trie[u].nxt[bt], depth - 1, first, ax);
  }
  void clear() { trie.clear(); }
};
honey lv[2] = {honey(0), honey(1)};
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
  for (int i = 0, l, r; i < m; ++i) {
    scanf("%d%d", &l, &r);
    --l, --r;
    q[l / Z].push_back(query(l, r, i));
  }
  for (int i = 1; i <= MAX; ++i) f[i] = i ^ f[i - 1];
  for (int bucket = 0; bucket < Z; ++bucket) {
    if (q[bucket].size() == 0) continue;
    sort(q[bucket].begin(), q[bucket].end());
    int idx = bucket * Z + Z;
    int ed = min(n - 1, bucket * Z + Z - 1);
    lv[0].clear();
    lv[1].clear();
    int mx = 0;
    for (int j = 0; j < q[bucket].size(); ++j) {
      query &sh = q[bucket][j];
      while (idx <= sh.r) {
        lv[0].insert(0, LOGN, f[a[idx] - 1], a[idx], 1);
        mx = max(mx, lv[0].search(0, LOGN, f[a[idx]], a[idx]));
        lv[1].insert(0, LOGN, f[a[idx]], a[idx], 1);
        mx = max(mx, lv[1].search(0, LOGN, f[a[idx] - 1], a[idx]));
        idx++;
      }
      ans[sh.idx] = mx;
      int lf = sh.l, rf = min(ed, sh.r);
      for (int p = lf; p <= rf; ++p) {
        lv[0].insert(0, LOGN, f[a[p] - 1], a[p], 1);
        lv[1].insert(0, LOGN, f[a[p]], a[p], 1);
      }
      for (int p = lf; p <= rf; ++p) {
        ans[sh.idx] = max(ans[sh.idx], lv[0].search(0, LOGN, f[a[p]], a[p]));
        ans[sh.idx] =
            max(ans[sh.idx], lv[1].search(0, LOGN, f[a[p] - 1], a[p]));
      }
      for (int p = lf; p <= rf; ++p) {
        lv[0].insert(0, LOGN, f[a[p] - 1], a[p], 0);
        lv[1].insert(0, LOGN, f[a[p]], a[p], 0);
      }
    }
  }
  for (int i = 0; i < m; ++i) {
    printf("%d\n", ans[i]);
  }
  return 0;
}
