#include <bits/stdc++.h>
using namespace std;
struct Trie {
  struct node {
    int nxt[2];
    int val;
    node() { nxt[0] = nxt[1] = val = -1; }
  };
  vector<node> T;
  int sz;
  function<bool(int, int)> cmp;
  Trie(int p, function<bool(int, int)> Cmp = less<int>()) : cmp(Cmp) {
    sz = p;
    T.push_back(node());
  }
  void add(int f, int first) {
    int cur = 0;
    T[cur].val = ((!sz || cmp(first, T[cur].val)) ? first : T[cur].val);
    for (int i = 24; i >= 0; --i) {
      int v = (f & (1 << i)) > 0;
      if (T[cur].nxt[v] == -1) {
        T[cur].nxt[v] = ++sz;
        T.push_back(node());
        T[sz].val = first;
      }
      cur = T[cur].nxt[v];
      if (cmp(first, T[cur].val)) T[cur].val = first;
    }
  }
  int get(int cur, int dep, int num, const int& first, const int f) {
    if (cur == -1) cout << first << ' ' << f << endl;
    ;
    if (dep < 0) return num;
    int k = !(f & (1 << dep));
    if (T[cur].nxt[k] != -1 && !cmp(first, T[T[cur].nxt[k]].val))
      return get(T[cur].nxt[k], dep - 1, num + (k << dep), first, f);
    else
      return get(T[cur].nxt[!k], dep - 1, num + ((!k) << dep), first, f);
  }
};
int get_xor(int first) {
  switch (first & 3) {
    case 0:
      return first;
    case 1:
      return 1;
    case 2:
      return first + 1;
    default:
      return 0;
  }
}
int N, M;
int sqrtN;
vector<int> Q[500];
pair<int, int> Qr[5001];
int A[50001], ans[5001];
Trie Left(0, greater<int>()), Right(0, less<int>());
bool query_Rcmp(const int& first, const int& second) {
  return Qr[first].second < Qr[second].second;
}
int get_max(Trie& L, Trie& R, int first) {
  int ans = 0;
  if (R.sz && !R.cmp(first, R.T[0].val))
    ans = max(
        ans, (get_xor(first - 1) ^ R.get(0, 24, 0, first, get_xor(first - 1))));
  if (L.sz && !L.cmp(first, L.T[0].val))
    ans = max(ans, (get_xor(first) ^ L.get(0, 24, 0, first, get_xor(first))));
  return ans;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> N >> M;
  sqrtN = sqrt(N) + 1;
  for (int i = 1; i <= N; ++i) cin >> A[i];
  for (int i = 1; i <= M; ++i) {
    cin >> Qr[i].first >> Qr[i].second;
    Q[Qr[i].first / sqrtN].push_back(i);
  }
  for (int i = 0; i <= sqrtN; ++i) {
    sort(Q[i].begin(), Q[i].end(), query_Rcmp);
    int maxL = 0;
    for (int j = 0; j < (int)Q[i].size(); ++j)
      maxL = max(maxL, Qr[Q[i][j]].first);
    int cur = maxL, curMx = 0;
    Left = Trie(0, less<int>()), Right = Trie(0, greater<int>());
    for (int j = 0; j < (int)Q[i].size(); ++j) {
      int L = Qr[Q[i][j]].first, R = Qr[Q[i][j]].second, id = Q[i][j];
      while (cur <= R) {
        Left.add(get_xor(A[cur] - 1), A[cur]);
        Right.add(get_xor(A[cur]), A[cur]);
        curMx = max(curMx, get_max(Left, Right, A[cur]));
        ++cur;
      }
      Trie TmpL(0, less<int>()), TmpR(0, greater<int>());
      ans[id] = curMx;
      for (int k = L; k < min(maxL, R + 1); ++k) {
        TmpL.add(get_xor(A[k] - 1), A[k]);
        TmpR.add(get_xor(A[k]), A[k]);
        ans[id] = max(ans[id], get_max(TmpL, TmpR, A[k]));
        ans[id] = max(ans[id], get_max(Left, Right, A[k]));
      }
    }
  }
  for (int i = 1; i <= M; ++i) printf("%d\n", ans[i]);
}
