#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9, MOD = 1e9 + 7, N = 1e5 + 1, M = 20;
void setIO(string name = "") {
  ios::sync_with_stdio(false);
  cin.tie(0);
  if (name.size()) {
    freopen((name + ".in").c_str(), "r", stdin);
    freopen((name + ".out").c_str(), "w", stdout);
  }
}
int n, m, a[N], s, pxor[1000001], ans[N];
void pre() {
  pxor[0] = 0;
  for (int i = 1; i < 1000001; i++) pxor[i] = pxor[i - 1] ^ i;
}
string bit(int j) {
  string ans;
  for (int i = 0; i < M; i++) {
    ans += (j & 1) + '0';
    j >>= 1;
  }
  reverse(ans.begin(), ans.end());
  return ans;
}
struct node1 {
  int mx = -INF;
  node1 *nxt[2]{};
};
struct node2 {
  int mn = INF;
  node2 *nxt[2]{};
};
node1 *rt1 = new node1();
node2 *rt2 = new node2();
void insert1(node1 *o, int i) {
  string s = bit(pxor[i]);
  for (char c : s) {
    if (!o->nxt[c - '0']) o->nxt[c - '0'] = new node1();
    o = o->nxt[c - '0'];
    o->mx = max(o->mx, i);
  }
}
void insert2(node2 *o, int i) {
  string s = bit(pxor[i]);
  for (char c : s) {
    if (!o->nxt[c - '0']) o->nxt[c - '0'] = new node2();
    o = o->nxt[c - '0'];
    o->mn = min(o->mn, i);
  }
}
void insert(int i) {
  insert1(rt1, i);
  insert2(rt2, i - 1);
}
int get1(node1 *o, int i) {
  string s = bit(pxor[i]);
  int ans = 0, shift = M - 1;
  for (char c : s) {
    int tmp = 1 ^ (c - '0');
    if (o->nxt[tmp] && o->nxt[tmp]->mx > i) {
      o = o->nxt[tmp];
      ans += (1 << shift);
    } else if (o->nxt[1 ^ tmp] && o->nxt[1 ^ tmp]->mx > i) {
      o = o->nxt[tmp ^ 1];
    } else
      return 0;
    shift--;
  }
  return ans;
}
int get2(node2 *o, int i) {
  string s = bit(pxor[i]);
  int ans = 0, shift = M - 1;
  for (char c : s) {
    int tmp = 1 ^ (c - '0');
    if (o->nxt[tmp] && o->nxt[tmp]->mn < i) {
      o = o->nxt[tmp];
      ans += (1 << shift);
    } else if (o->nxt[1 ^ tmp] && o->nxt[1 ^ tmp]->mn < i) {
      o = o->nxt[tmp ^ 1];
    } else
      return 0;
    shift--;
  }
  return ans;
}
int get(int i) { return max(get1(rt1, i - 1), get2(rt2, i)); }
void clearall(node1 *o) {
  o->mx = -INF;
  if (o->nxt[0] && o->nxt[0]->mx != -INF) clearall(o->nxt[0]);
  if (o->nxt[1] && o->nxt[1]->mx != -INF) clearall(o->nxt[1]);
}
void clearall(node2 *o) {
  o->mn = INF;
  if (o->nxt[0] && o->nxt[0]->mn != INF) clearall(o->nxt[0]);
  if (o->nxt[1] && o->nxt[1]->mn != INF) clearall(o->nxt[1]);
}
void init() {
  clearall(rt1);
  clearall(rt2);
}
struct query {
  int l, r, id, bl;
  query(int ll, int rr, int i) : l(ll), r(rr), id(i), bl(l / s) {}
  bool operator<(const query &other) const {
    return make_pair(bl, r) < make_pair(other.bl, other.r);
  }
};
query make_query(int ll, int rr, int i) { return query(ll, rr, i); }
vector<query> qry;
signed main() {
  setIO();
  pre();
  cin >> n >> m;
  s = ceil(sqrt(n));
  for (int i = 0; i < n; i++) cin >> a[i];
  for (int i = 0; i < m; i++) {
    int l, r;
    cin >> l >> r;
    qry.push_back(make_query(l - 1, r - 1, i));
  }
  sort(qry.begin(), qry.end());
  for (int i = 0, j = 0; i < m; i = j) {
    while (j < m && qry[j].bl == qry[i].bl) j++;
    int lmx = 0, mid = j, right, nowmx = 0;
    for (int k = i; k < j; k++) right = lmx = max(lmx, qry[k].l);
    for (int k = i; k < j; k++)
      if (qry[k].r > lmx) {
        mid = k;
        break;
      }
    init();
    for (int k = mid; k < j; k++) {
      ans[qry[k].id] = nowmx;
      while (right <= qry[k].r) {
        insert(a[right]);
        nowmx = ans[qry[k].id] = max(ans[qry[k].id], get(a[right]));
        right++;
      }
      for (int l = lmx; l >= qry[k].l; l--) {
        ans[qry[k].id] = max(ans[qry[k].id], get(a[l]));
      }
    }
    for (int k = i; k < j; k++) {
      init();
      for (int l = min(qry[k].r, lmx); l >= qry[k].l; l--) {
        insert(a[l]);
        ans[qry[k].id] = max(ans[qry[k].id], get(a[l]));
      }
    }
  }
  for (int i = 0; i < m; i++) cout << ans[i] << '\n';
}
