#include <bits/stdc++.h>
using namespace std;
int ans[50005], prefix_xor[1000000 + 1], trie[40 * 50005][2], mini[40 * 50005],
    maxi[40 * 50005], ctr, a[50005];
int start[300], finish[300], block[50005], block_no, sz = 250,
                                                     dp[300][300][300];
vector<pair<pair<int, int>, int> > query[300];
int getbit(int value, int bit) {
  int x = value & (1 << bit);
  if (x != 0) return 1;
  return 0;
}
struct TRIE {
  int root;
  TRIE() {
    ctr++;
    root = ctr;
    trie[root][0] = trie[root][1] = 0;
  }
  void insert(int value, int actual_value) {
    int cur = root;
    for (int i = 19; i >= 0; i--) {
      int bit = getbit(value, i);
      if (!trie[cur][bit]) {
        ctr++;
        trie[cur][bit] = ctr;
        trie[ctr][0] = trie[ctr][1] = 0;
        mini[ctr] = maxi[ctr] = actual_value;
        cur = trie[cur][bit];
      } else {
        cur = trie[cur][bit];
        mini[cur] = min(mini[cur], actual_value);
        maxi[cur] = max(maxi[cur], actual_value);
      }
    }
  }
  int query(int value, int actual_value, int is_bigger) {
    int cur = root, res = 0;
    for (int i = 19; i >= 0; i--) {
      int bit = getbit(value, i);
      if (trie[cur][1 - bit]) {
        if (is_bigger && mini[trie[cur][1 - bit]] <= actual_value) {
          res += (1 << i);
          cur = trie[cur][1 - bit];
        } else if (!is_bigger && maxi[trie[cur][1 - bit]] >= actual_value) {
          res += (1 << i);
          cur = trie[cur][1 - bit];
        } else
          cur = trie[cur][1 - bit];
      } else
        cur = trie[cur][bit];
    }
    return res;
  }
};
int helper(int val1, int val2) {
  if (val1 > val2) swap(val1, val2);
  return (prefix_xor[val2] ^ prefix_xor[val1 - 1]);
}
int index(int ind, int block_index) { return ind - (block_index - 1) * sz; }
int main() {
  ios::sync_with_stdio(false);
  ;
  cin.tie(0);
  ;
  int i, j, n, q, x, y, k, len, l, r, ptr, ind;
  cin >> n >> q;
  for (i = 1; i <= n; i++) cin >> a[i];
  prefix_xor[0] = 0;
  for (i = 1; i <= 1000000; i++) prefix_xor[i] = i ^ prefix_xor[i - 1];
  for (i = 1; i <= n; i++) {
    block_no++;
    start[block_no] = i;
    for (j = i; j <= min(n, i + sz - 1); j++) block[j] = block_no;
    finish[block_no] = min(n, i + sz - 1);
    i = i + sz - 1;
  }
  for (i = 1; i <= block_no; i++) {
    for (j = start[i]; j <= finish[i]; j++)
      dp[i][index(j, i)][index(j, i)] = a[j];
    for (len = 2; len <= finish[i] - start[i] + 1; len++) {
      for (j = start[i]; j + len - 1 <= finish[i]; j++) {
        k = j + len - 1;
        dp[i][index(j, i)][index(k, i)] =
            max(dp[i][index(j, i)][index(k, i)],
                dp[i][index(j, i)][index(k - 1, i)]);
        dp[i][index(j, i)][index(k, i)] =
            max(dp[i][index(j, i)][index(k, i)],
                dp[i][index(j + 1, i)][index(k, i)]);
        dp[i][index(j, i)][index(k, i)] =
            max(dp[i][index(j, i)][index(k, i)],
                dp[i][index(j + 1, i)][index(k - 1, i)]);
        dp[i][index(j, i)][index(k, i)] =
            max(dp[i][index(j, i)][index(k, i)], helper(a[j], a[k]));
      }
    }
  }
  for (i = 1; i <= q; i++) {
    cin >> l >> r;
    if (block[l] == block[r]) {
      ans[i] = dp[block[l]][index(l, block[l])][index(r, block[r])];
      continue;
    }
    query[block[l]].push_back({{r, l}, i});
  }
  for (i = 1; i <= block_no; i++) {
    if (!query[i].size()) continue;
    sort(query[i].begin(), query[i].end());
    ptr = start[i + 1];
    ctr = 0;
    TRIE smaller, bigger;
    int got = 0;
    for (auto it : query[i]) {
      r = it.first.first;
      l = it.first.second;
      ind = it.second;
      while (ptr <= r) {
        smaller.insert(prefix_xor[a[ptr] - 1], a[ptr]);
        bigger.insert(prefix_xor[a[ptr]], a[ptr]);
        got = max(got, smaller.query(prefix_xor[a[ptr]], a[ptr], 1));
        got = max(got, bigger.query(prefix_xor[a[ptr] - 1], a[ptr], 0));
        ptr++;
      }
      ans[ind] = max(ans[ind], got);
      ans[ind] = max(
          ans[ind],
          dp[block[l]][index(l, block[l])][index(finish[block[l]], block[l])]);
      for (j = l; j <= finish[block[l]]; j++) {
        ans[ind] = max(ans[ind], smaller.query(prefix_xor[a[j]], a[j], 1));
        ans[ind] = max(ans[ind], bigger.query(prefix_xor[a[j] - 1], a[j], 0));
      }
    }
  }
  for (i = 1; i <= q; i++) cout << ans[i] << "\n";
  return 0;
}
