#include <bits/stdc++.h>   inline int getInt() {     int s;     scanf( %d , &s);     return s;   }   using namespace std;   struct Node {     long long highest;     int mxL;     int mxR;     int idxL;     int idxR;     Node(long long h, long long l, long long r, int il, int ir)         : highest(h), mxL(l), mxR(r), idxL(il), idxR(ir) {}   };   template <typename Data, typename Func>   class SegmentTree {    public:     int n;     std::vector<Data> data;     Func f;     Data d;     Data query(int a, int b, int k, int l, int r) const {       if (r <= a || b <= l) return d;       if (a <= l && r <= b)         return data[k];       else {         const Data v1 = query(a, b, k * 2 + 1, l, (l + r) / 2);         const Data v2 = query(a, b, k * 2 + 2, (l + r) / 2, r);         return f(v1, v2);       }     }     SegmentTree(int nn, Func f, Data d) : f(f), d(d) {       n = 1;       while (n < nn) n *= 2;       data = std::vector<Data>(2 * n, d);     }     void update(int k, const Data &a) {       k += n - 1;       data[k] = a;       while (k > 0) {         k = (k - 1) / 2;         data[k] = f(data[k * 2 + 1], data[k * 2 + 2]);       }     }     Data query(int a, int b) const { return query(a, b, 0, 0, n); }   };   template <typename Data, typename Func>   SegmentTree<Data, Func> segtree(int numberOfElements, Data defaultValue,                                   Func mergeFunc) {     return SegmentTree<Data, Func>(numberOfElements, mergeFunc, defaultValue);   }   int main() {     const int n = getInt();     const int m = getInt();     vector<long long> d(n);     vector<long long> h(n);     for (int i = 0; i < (int)(n); i++) d[i] = getInt();     for (int i = 0; i < (int)(n); i++) h[i] = getInt();     vector<long long> ps(2 * n + 1);     for (int i = 0; i < (int)(2 * n); i++) ps[i + 1] = ps[i] + d[i % n];     const Node df(-1, 0, 0, 0, 0);     auto calc = [&](int l, int r) {       if (l == r) return 0ll;       return ps[r] - ps[l] + 2 * (h[l % n] + h[r % n]);     };     auto st = segtree(2 * n, df, [&](const Node &lhs, const Node &rhs) {       if (lhs.highest == -1) return rhs;       if (rhs.highest == -1) return lhs;       const int idxL = lhs.idxL;       const int idxR = rhs.idxR;       const long long la = calc(idxL, lhs.mxL);       const long long lb = calc(idxL, rhs.mxL);       const long long lc = calc(idxL, rhs.idxL);       const long long ml = max(max(la, lb), lc);       const int mxL = lc > la && lc > lb ? rhs.idxL : la > lb ? lhs.mxL : rhs.mxL;       const long long ra = calc(lhs.mxR, idxR);       const long long rb = calc(rhs.mxR, idxR);       const long long rc = calc(lhs.idxR, idxR);       const long long mr = max(max(ra, rb), rc);       const int mxR = rc > ra && rc > rb ? lhs.idxR : rb > ra ? rhs.mxR : lhs.mxR;       const long long t =           max(max(calc(lhs.mxR, rhs.mxL), calc(lhs.mxR, rhs.idxL)),               max(calc(lhs.idxR, rhs.mxL), calc(lhs.idxR, rhs.idxL)));       const long long highest = max(           t,           max(max(max(lhs.highest, rhs.highest), max(ml, mr)), calc(idxL, idxR)));       return Node(highest, mxL, mxR, idxL, idxR);     });     for (int i = 0; i < (int)(2 * n); i++) st.update(i, Node(0, i, i, i, i));     for (int i = 0; i < (int)(m); i++) {       const int a = getInt() - 1;       const int b = getInt() - 1;       const int aa = b + 1;       const int bb = a <= b ? a + n - 1 : a - 1;       const Node ans = st.query(aa, bb + 1);       cout << ans.highest << endl;     }     return 0;   }