#include <bits/stdc++.h>
using namespace std;
inline int Read() {
  int Num = 0, Flag = 1;
  char ch;
  do {
    ch = getchar();
    if (ch == '-') Flag *= -1;
  } while (ch < '0' || ch > '9');
  do {
    Num = Num * 10 + ch - '0';
    ch = getchar();
  } while (ch >= '0' && ch <= '9');
  return Num;
}
namespace Trie {
class Node {
 public:
  Node *Next[2];
  int Size;
} * Root1, *Root2;
inline Node *New() { return (Node *)calloc(1, sizeof(Node)); }
inline void Insert(Node *x, int Num) {
  ++x->Size;
  int A[30] = {0};
  for (int i = 20; i; --i) A[i] = Num & 1, Num >>= 1;
  for (int i = 1; i <= 20; ++i) {
    if (!x->Next[A[i]]) x->Next[A[i]] = New();
    x = x->Next[A[i]];
    ++x->Size;
  }
}
inline void Erase(Node *x, int Num) {
  --x->Size;
  int A[30] = {0};
  for (int i = 20; i; --i) A[i] = Num & 1, Num >>= 1;
  for (int i = 1; i <= 20; ++i) {
    x = x->Next[A[i]];
    --x->Size;
  }
}
inline int Query(Node *x, int Num, int Flag) {
  int A[21] = {0}, Ans = 0, temp = Num;
  for (int i = 20; i; --i) A[i] = Num & 1, Num >>= 1;
  for (int i = 1; i <= 20; ++i) {
    Ans <<= 1;
    if (A[i] == Flag) {
      if (x->Next[A[i]] && x->Next[A[i]]->Size)
        x = x->Next[A[i]];
      else
        return temp;
    } else if (x->Next[A[i] ^ 1] && x->Next[A[i] ^ 1]->Size) {
      Ans += 1;
      if (A[i] ^ 1 == Flag) Flag = 3;
      x = x->Next[A[i] ^ 1];
    } else {
      if (A[i] == Flag) Flag = 3;
      x = x->Next[A[i]];
    }
  }
  return Ans;
}
void Clear(Node *x) {
  if (!x) return;
  Clear(x->Next[0]);
  Clear(x->Next[1]);
  free(x);
}
inline void Initialize() {
  Clear(Root1);
  Clear(Root2);
  Root1 = New();
  Root2 = New();
}
}  // namespace Trie
class Ask {
 public:
  int Left, Right, k, id;
  inline bool operator<(Ask const &a) const {
    if (k != a.k) return k < a.k;
    return Right < a.Right;
  }
} Asks[1000005];
int N, M, Size, Total, Answer;
int A[1000005], S[1000005], Ans[1000005];
inline void Add(int i, int id) {
  int Num1 = S[A[i]], Num2 = S[A[i] - 1];
  Trie::Insert(Trie::Root1, Num1);
  Trie::Insert(Trie::Root2, Num2);
  Ans[id] = max(Ans[id], Trie::Query(Trie::Root1, Num2, 1));
  Ans[id] = max(Ans[id], Trie::Query(Trie::Root2, Num1, 0));
  Ans[id] = max(Ans[id], A[i]);
}
int main() {
  cin >> N >> M;
  for (int i = 1; i <= N; ++i) A[i] = Read();
  for (int i = 1; i <= 1000000; ++i) S[i] = S[i - 1] ^ i;
  Size = (int)sqrt(N);
  for (int i = 1; i <= M; ++i) {
    int Left = Read(), Right = Read();
    if (Right - Left <= Size) {
      Trie::Initialize();
      for (int j = Left; j <= Right; ++j) Add(j, i);
      continue;
    }
    Asks[++Total].Left = Left;
    Asks[Total].Right = Right;
    Asks[Total].id = i;
    Asks[Total].k = (Asks[Total].Left - 1) / Size + 1;
  }
  sort(Asks + 1, Asks + Total + 1);
  for (int i = 1; i <= M; ++i) {
    int Begin = Asks[i].k * Size, ID = Asks[i].id;
    if (Asks[i].k != Asks[i - 1].k) {
      Trie::Initialize();
      for (int j = Begin + 1; j <= Asks[i].Right; ++j) Add(j, ID);
      Answer = Ans[ID];
      for (int j = Asks[i].Left; j <= Begin; ++j) Add(j, ID);
    } else {
      Ans[ID] = Answer;
      for (int j = Asks[i - 1].Right + 1; j <= Asks[i].Right; ++j) Add(j, ID);
      Answer = max(Answer, Ans[ID]);
      for (int j = Begin; j >= Asks[i].Left; --j) Add(j, ID);
    }
    for (int j = Asks[i].Left; j <= Begin; ++j) {
      Trie::Erase(Trie::Root1, S[A[j]]);
      Trie::Erase(Trie::Root2, S[A[j] - 1]);
    }
  }
  for (int i = 1; i <= M; ++i) printf("%d\n", Ans[i]);
  fclose(stdin);
  fclose(stdout);
  return 0;
}
