#include <bits/stdc++.h>
using namespace std;
struct data {
  int l, r, idx;
  int lsq;
  bool operator<(const data &a) const {
    return lsq == a.lsq ? r < a.r : lsq < a.lsq;
  }
};
int pre[1000006];
struct Trie {
  vector<int> trie[2][2];
  vector<int> maxi, mini;
  int curNode1, curNode2;
  Trie() {
    trie[0][0] = vector<int>(1000005);
    trie[1][0] = vector<int>(1000005);
    trie[0][1] = vector<int>(1000005);
    trie[1][1] = vector<int>(1000005);
    maxi = vector<int>(1000005);
    mini = vector<int>(1000005, INT_MAX);
    curNode1 = 0;
    curNode2 = 0;
  }
  void insertL(int n, int idx) {
    int cur = 0;
    for (int i = 19; i >= 0; i--) {
      int c = (n & (1 << i)) > 0;
      if (trie[0][c][cur] == 0) trie[0][c][cur] = ++curNode1;
      cur = trie[0][c][cur];
      mini[cur] = min(mini[cur], idx);
    }
  }
  void insertR(int n, int idx) {
    int cur = 0;
    for (int i = 19; i >= 0; i--) {
      int c = (n & (1 << i)) > 0;
      if (trie[1][c][cur] == 0) trie[1][c][cur] = ++curNode2;
      cur = trie[1][c][cur];
      maxi[cur] = max(maxi[cur], idx);
    }
  }
  void init() {
    for (int i = 0; i <= curNode1; i++) {
      trie[0][0][i] = 0, trie[0][1][i] = 0;
      mini[i] = INT_MAX;
    }
    for (int i = 0; i <= curNode2; i++) {
      trie[1][0][i] = 0, trie[1][1][i] = 0;
      maxi[i] = 0;
    }
    curNode1 = 0;
    curNode2 = 0;
  }
  int searchL(int n, int val) {
    int cur = 0;
    int ret = 0;
    for (int i = 19; i >= 0; i--) {
      int c = (n & (1 << i)) > 0;
      if (trie[0][c ^ 1][cur] && mini[trie[0][c ^ 1][cur]] < val)
        cur = trie[0][c ^ 1][cur], ret |= (1 << i);
      else if (mini[trie[0][c][cur]] >= val)
        return 0;
      else
        cur = trie[0][c][cur];
    }
    return ret;
  }
  int searchR(int n, int val) {
    int cur = 0;
    int ret = 0;
    for (int i = 19; i >= 0; i--) {
      int c = (n & (1 << i)) > 0;
      if (trie[1][c ^ 1][cur] && maxi[trie[1][c ^ 1][cur]] > val)
        cur = trie[1][c ^ 1][cur], ret |= (1 << i);
      else if (maxi[trie[1][c][cur]] <= val)
        return 0;
      else
        cur = trie[1][c][cur];
    }
    return ret;
  }
  void insert(int a) {
    insertL(pre[a], a);
    insertR(pre[a + 1], a);
  }
  int search(int a) {
    return max(searchL(pre[a + 1], a), max(a, searchR(pre[a], a)));
  }
};
int ans[100005];
int main() {
  int sq = 224;
  pre[1000001] = 1000001;
  for (int i = 1000000; i >= 1; i--) pre[i] = i ^ pre[i + 1];
  int n, m;
  scanf("%d %d", &n, &m);
  int ara[n];
  for (int i = 0; i < n; i++) {
    int a;
    scanf("%d", &a);
    ara[i] = a;
  }
  data Q[m];
  for (int i = 0; i < m; i++) {
    int l, r;
    scanf("%d %d", &l, &r);
    l--, r--;
    Q[i].l = l;
    Q[i].r = r;
    Q[i].lsq = l / sq;
    Q[i].idx = i;
  }
  sort(Q, Q + m);
  int prv = -1;
  int L, R, pL, pR;
  Trie tmp, tl, tr;
  int trmax = 0;
  for (int i = 0; i < m; i++) {
    int L = Q[i].l, R = Q[i].r;
    if (R - L <= sq + 5) {
      tmp.init();
      int maxi = 0;
      for (int j = L; j <= R; j++) {
        tmp.insert(ara[j]);
        maxi = max(maxi, tmp.search(ara[j]));
      }
      ans[Q[i].idx] = maxi;
      continue;
    }
    if (prv != Q[i].lsq) {
      prv = Q[i].lsq;
      tr.init();
      trmax = 0;
      pR = Q[i].lsq * sq + sq - 1;
    }
    assert(pR <= R);
    while (pR + 1 <= R) {
      tr.insert(ara[pR + 1]);
      trmax = max(trmax, tr.search(ara[pR + 1]));
      pR++;
    }
    pL = Q[i].lsq * sq + sq;
    tl.init();
    int maxi = trmax;
    while (L <= pL - 1) {
      tl.insert(ara[pL - 1]);
      maxi = max(tl.search(ara[pL - 1]), maxi);
      maxi = max(tr.search(ara[pL - 1]), maxi);
      pL--;
    }
    ans[Q[i].idx] = maxi;
  }
  for (int i = 0; i < m; i++) printf("%d\n", ans[i]);
  return 0;
}
