#include <cstdio> #define NN 100001 #define MAXN NN*3 #define lc(x) ((x)<<1) #define rc(x) ((x)<<1|1) #define getmid(a,b) ((a)+(b))>>1 #define max(a,b) ((a)>(b)?(a):(b)) struct point { int s,e; // 点的起始坐标跟末尾坐标 int cnt; // 点的数跟那个数出现的次数 }; int tree[MAXN]; // 线段树 point pts[NN]; // 缩成的点 int ori[NN]; // 原始输入的数 int bel[NN]; // 第i个数所在点分组的编号 int n; // 输入的规模 int t; // 缩点后的规模 void ini() { t = 1; pts[t].s = 1; pts[t].e = 1; pts[t].cnt = 1; bel[1] = t; for (int i = 2; i <= n; ++i) { if (ori[i]==ori[i-1]) { pts[t].cnt++; pts[t].e = i; } else { t++; pts[t].s = i; pts[t].e = i; pts[t].cnt = 1; } bel[i] = t; } } void build(int l, int r, int id) { if (l==r) { tree[id] = pts[l].cnt; return; } int mid = getmid(l,r); build(l, mid, lc(id)); build(mid+1, r, rc(id)); if(tree[lc(id)] > tree[rc(id)]) tree[id] = tree[lc(id)]; else tree[id] = tree[rc(id)]; } int query(int a, int b, int l, int r, int id) { if (a==l && b==r) return tree[id]; int mid = getmid(l, r); if (b <= mid) { return query(a, b, l, mid, lc(id)); } else if (a > mid) { return query(a, b, mid+1, r, rc(id)); } else { int lp = query(a, mid, l, mid, lc(id)); int rp = query(mid+1, b, mid+1, r, rc(id)); return max(lp, rp); } } int solve(int a, int b) { int lpart, rpart; if (bel[a]==bel[b]) { // a跟b属于同一段 return b - a + 1; } else if(bel[a]+1 == bel[b]) { // a跟b相邻,最大的频率是max( [a..lpoint->end], [rpoint->start..b] ) lpart = pts[ bel[a] ].e - a + 1; rpart = b - pts[ bel[b] ].s + 1; return max(lpart, rpart); } else { // a跟b中间有间隔,最大的频率是max( [a..lpoint->end], [rpoint->start..b], query(bel[a]+1, bel[b]-1) ) lpart = pts[ bel[a] ].e - a + 1; rpart = b - pts[ bel[b] ].s + 1; int large = max(lpart, rpart); return max(large, query(bel[a]+1, bel[b]-1, 1, t, 1)); } } int main () { int m,a,b; while(scanf("%d", &n) && n) { scanf("%d", &m); for (int i = 1; i <= n; ++i) scanf("%d", &ori[i]); ini(); build(1, t, 1); for (int i = 0; i < m; ++i) { scanf("%d%d", &a, &b); printf("%d/n", solve(a, b)); } } return 0; }