#include <bits/stdc++.h>
using namespace std;
const int nsz = 5e4, msz = 5e3, asz = 1e6, lgsz = 20, ndsz = 5 * nsz * lgsz;
int n, m, pre[asz + 5], a[nsz + 5];
int bsz, cl, cr, cur, ans[msz + 5];
int rt1[nsz + 5], rt2[nsz + 5];
struct persistent_trie_1 {
  int sz, rt, g[ndsz][2], mn[ndsz + 5], t[ndsz + 5];
  persistent_trie_1() { rt = ++sz; }
  void inline ins(int w, int time, int at_least, int &rt, int p) {
    int u = rt = ++sz;
    for (int k = lgsz; k >= 0; --k) {
      int c = w >> k & 1;
      g[u][!c] = g[p][!c];
      g[u][c] = ++sz;
      u = g[u][c], p = g[p][c];
      t[u] = time;
      mn[u] = p ? min(mn[p], at_least) : at_least;
    }
  }
  int inline qry(int w, int time, int at_least, int u) {
    int res = 0;
    for (int k = lgsz; k >= 0; --k) {
      int c = w >> k & 1, v1 = g[u][!c], v2 = g[u][c];
      if (v1 && time <= t[v1] && at_least >= mn[v1]) {
        res += 1 << k;
        u = v1;
      } else {
        u = v2;
      }
    }
    return res;
  }
};
persistent_trie_1 tr1;
struct persistent_trie_2 {
  int sz, rt, g[ndsz][2], mx[ndsz + 5], t[ndsz + 5];
  persistent_trie_2() { rt = ++sz; }
  void inline ins(int w, int time, int at_most, int &rt, int p) {
    int u = rt = ++sz;
    for (int k = lgsz; k >= 0; --k) {
      int c = w >> k & 1;
      g[u][!c] = g[p][!c];
      g[u][c] = ++sz;
      u = g[u][c], p = g[p][c];
      t[u] = time;
      mx[u] = p ? max(mx[p], at_most) : at_most;
    }
  }
  int inline qry(int w, int time, int at_most, int u) {
    int res = 0;
    for (int k = lgsz; k >= 0; --k) {
      int c = w >> k & 1, v1 = g[u][!c], v2 = g[u][c];
      if (v1 && time <= t[v1] && at_most <= mx[v1]) {
        res += 1 << k;
        u = v1;
      } else {
        u = v2;
      }
    }
    return res;
  }
};
persistent_trie_2 tr2;
struct query {
  bool done;
  int id, l, r;
  query(int id = 0, int l = 0, int r = 0) {
    this->id = id, this->l = l, this->r = r;
    done = 0;
  }
};
query q[msz + 5];
bool inline operator<(query a, query b) {
  int ba = a.l / bsz, bb = b.l / bsz;
  return ba != bb ? ba < bb : a.r < b.r;
}
void inline prefix_init() {
  for (int i = 1; i <= asz; ++i) {
    pre[i] = pre[i - 1] ^ i;
  }
}
void inline ins(int id, int w) {
  tr1.ins(pre[w - 1], id, w, rt1[id], rt1[id - 1]);
  tr2.ins(pre[w], id, w, rt2[id], rt2[id - 1]);
}
int inline qry1(int l, int r, int w) { return tr1.qry(pre[w], l, w, rt1[r]); }
int inline qry2(int l, int r, int w) {
  return tr2.qry(pre[w - 1], l, w, rt2[r]);
}
void inline mo_ins(int id, int w) {
  cur = max(cur, qry1(cl, cr, w));
  cur = max(cur, qry2(cl, cr, w));
}
void inline mo_solve() {
  for (int i = 1; i <= m; ++i) {
    int l = q[i].l, r = q[i].r;
    if (l / bsz == r / bsz) {
      int res = 0;
      for (int i = l; i <= r; ++i) {
        res = max(res, qry1(l, r, a[i]));
      }
      ans[q[i].id] = res;
      q[i].done = 1;
    }
  }
  int tmp = 0;
  for (int i = 1; i <= m; ++i) {
    if (i == 1 || q[i].l / bsz != q[i - 1].l / bsz) {
      cr = (q[i].l / bsz + 1) * bsz;
      tmp = cur = 0;
    }
    if (q[i].done) continue;
    cl = (q[i].l / bsz + 1) * bsz + 1;
    cur = tmp;
    for (; cr < q[i].r; ++cr, mo_ins(cr, a[cr]))
      ;
    tmp = cur;
    for (; cl > q[i].l; --cl, mo_ins(cl, a[cl]))
      ;
    ans[q[i].id] = cur;
  }
}
int main() {
  prefix_init();
  scanf("%d%d", &n, &m);
  bsz = ceil((double)n / sqrt(m));
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &a[i]);
    ins(i, a[i]);
  }
  for (int i = 1; i <= m; ++i) {
    int l, r;
    scanf("%d%d", &l, &r);
    q[i] = query(i, l, r);
  }
  sort(q + 1, q + m + 1);
  mo_solve();
  for (int i = 1; i <= m; ++i) {
    printf("%d\n", ans[i]);
  }
}
