#include <iostream>
#include <stdio.h>
#include <cmath>
#define MAXN 200004
typedef long long ll;
using namespace std;
int n,m;

ll D[MAXN];
ll H[MAXN];
ll A[MAXN];

ll Max[MAXN][20];
int RMQ[MAXN][20];

void initMax(){
  for (int i=0;i<(n<<1);i++){
    Max[i][0]=A[i];
  }
  for (int i=2,p=1;i<=(n<<1);i=i<<1){
    for (int j=0;j+i<=(n<<1);j++){
      Max[j][p]=max(Max[j][p-1],Max[j+(i>>1)][p-1]);
    }
    p++;
  }
}

ll maxRMQ(int i,int f){
  int dis=log2(f-i+1);
  return max(Max[i][dis],Max[f-(1<<dis)+1][dis]);
}

void initRmq(){
  for (int i=0;i+1<(n<<1);i++){
    RMQ[i][1]=i;
  }
  for (int i=4,p=2;i<=(n<<1);i=i<<1){
    for (int j=0;j+i<=(n<<1);j++){
      int ini1,ini2,ini3;
      ll a,b,c;
      ini1=RMQ[j][p-1];
      ini2=RMQ[j+(i>>1)][p-1];
      ini3=j+(i>>1)-1;
      a=maxRMQ(ini1+1,j+i-1)-D[ini1]+H[ini1];
      b=maxRMQ(ini2+1,j+i-1)-D[ini2]+H[ini2];
      c=maxRMQ(ini3+1,j+i-1)-D[ini3]+H[ini3];
      if (a>b){
        if (a>c){
          RMQ[j][p]=ini1;
        } else {
          RMQ[j][p]=ini3;
        }
      } else {
        if (b>c){
          RMQ[j][p]=ini2;
        } else {
          RMQ[j][p]=ini3;
        }
      }
    }
    p++;
  }
}

ll queryRMQ(int i,int f){
  ll a,b;
  int dis=log2(f-i+1);
  int ini1=RMQ[i][dis];
  int ini2=RMQ[f-(1<<dis)+1][dis];
  a=maxRMQ(ini1+1,f)-D[ini1]+H[ini1];
  b=maxRMQ(ini2+1,f)-D[ini2]+H[ini2];
  return max(a,b);
}

int main (){
  scanf("%d %d",&n,&m);
  int scan;
  for (int i=1;i<=n;i++){
    scanf("%d",&scan);
    D[i]=scan;
    D[i+n]=D[i];
    D[i]+=D[i-1];
  }
  for (int i=n+1;i<(n<<1);i++){
    D[i]+=D[i-1];
  }
  for (int i=0;i<n;i++){
    scanf("%d",&scan);
    H[i]=scan;
    H[i]*=2;
    H[i+n]=H[i];
  }
  for (int i=0;i<(n<<1);i++){
    A[i]=H[i]+D[i];
  }
  initMax();
  initRmq();
  for (int i=0;i<m;i++){
    int a,b,in,fn;
    scanf("%d %d",&a,&b);
    a--;
    b--;
    if (a<=b){
      in=b+1;
      fn=a+n-1;
    } else {
      in=b+1;
      fn=a-1;
    }
    cout << queryRMQ(in,fn) << endl;
  }
  return 0;
}


#include <iostream>
#include <stdio.h>
#include <cmath>
#define MAXN 200004
typedef long long ll;
using namespace std;
int n,m;

ll D[MAXN];
ll S[MAXN];
ll R[MAXN];
ll H[MAXN];
ll A[MAXN];
ll B[MAXN];
ll Max[MAXN][20];
ll Rmax[MAXN][20];
int ID[MAXN][20];
int IDR[MAXN][20];

void initMax(){
  for (int i=0;i<(n<<1);i++){
    Max[i][0]=A[i];
    ID[i][0]=i;
    IDR[i][0]=i;
    Rmax[i][0]=B[i];
  }
  for (int i=2,p=1;i<=(n<<1);i=i<<1){
    for (int j=0;j+i<=(n<<1);j++){
      Max[j][p]=max(Max[j][p-1],Max[j+(i>>1)][p-1]);
      Rmax[j][p]=max(Rmax[j][p-1],Rmax[j+(i>>1)][p-1]);
      if (Max[j][p]==Max[j][p-1]){
        ID[j][p]=ID[j][p-1];
      } else {
        ID[j][p]=ID[j+(i>>1)][p-1];
      }
      if (Rmax[j][p]==Rmax[j][p-1]){
        IDR[j][p]=IDR[j][p-1];
      } else {
        IDR[j][p]=IDR[j+(i>>1)][p-1];
      }
    }
    p++;
  }
}

int idMax(int i,int f){
  int dis=log2(f-i+1);
  if (Max[i][dis]>Max[f-(1<<dis)+1][dis]){
    return ID[i][dis];
  }
  return ID[f-(1<<dis)+1][dis];
}

ll maxM(int i,int f){
  int dis=log2(f-i+1);
  return max(Max[i][dis],Max[f-(1<<dis)+1][dis]);
}

int idR(int i,int f){
  int dis=log2(f-i+1);
  if (Rmax[i][dis]>Rmax[f-(1<<dis)+1][dis]){
    return IDR[i][dis];
  }
  return IDR[f-(1<<dis)+1][dis];
}

ll maxR(int i,int f){
  int dis=log2(f-i+1);
  return max(Rmax[i][dis],Rmax[f-(1<<dis)+1][dis]);
}

int main (){
  scanf("%d %d",&n,&m);
  int scan;
  for (int i=1;i<=n;i++){
    scanf("%d",&scan);
    D[i]=scan;
    D[i+n]=D[i];
  }
  D[(n<<1)]=0;
  for (int i=0;i<n;i++){
    scanf("%d",&scan);
    H[i]=scan;
    H[i]=H[i]<<1;
    H[i+n]=H[i];
  }
  for (int i=1;i<=(n<<1);i++){
    S[i]=S[i-1]+D[i];
  }
  for (int i=(n<<1)-1;i>-1;i--){
    R[i]=R[i+1]+D[i];
  }
  for (int i=(n<<1)-1;i>-1;i--){
    B[i]=R[i+1]+H[i];
  }
  for (int i=0;i<(n<<1);i++){
    A[i]=S[i]+H[i];
  }
  initMax();
  for (int i=0;i<m;i++){
    int a,b,in,fn;
    scanf("%d %d",&a,&b);
    a--;
    b--;
    if (a<=b){
      in=b+1;
      fn=a+n-1;
    } else {
      in=b+1;
      fn=a-1;
    }
    int id=idMax(in+1,fn);
    int id2=idR(in,id-1);
    ll ans2=0;
    ll ans1=A[id]-S[id2]+H[id2];
    if (id+1<=fn){
      id2=idMax(id+1,fn);
      ans2=A[id2]-S[id]+H[id];
    }
    cout << max(ans1,ans2) << endl;
  }
  return 0;
}


#include <iostream>
#include <stdio.h>
#include <cmath>
#define MAXN 200004
typedef long long ll;
using namespace std;
int n,m;

ll D[MAXN];
ll H[MAXN];
ll A[MAXN];

ll Max[MAXN][20];
int RMQ[MAXN][20];

void initMax(){
  for (int i=0;i<(n<<1);i++){
    Max[i][0]=A[i];
  }
  for (int i=2,p=1;i<=(n<<1);i=i<<1){
    for (int j=0;j+i<=(n<<1);j++){
      Max[j][p]=max(Max[j][p-1],Max[j+(i>>1)][p-1]);
    }
    p++;
  }
}

ll maxRMQ(int i,int f){
  int dis=log2(f-i+1);
  return max(Max[i][dis],Max[f-(1<<dis)+1][dis]);
}

void initRmq(){
  for (int i=0;i+1<(n<<1);i++){
    RMQ[i][1]=i;
  }
  for (int i=4,p=2;i<=(n<<1);i=i<<1){
    for (int j=0;j+i<=(n<<1);j++){
      int ini1,ini2,ini3;
      ll a,b,c;
      ini1=RMQ[j][p-1];
      ini2=RMQ[j+(i>>1)][p-1];
      ini3=j+(i>>1)-1;
      a=maxRMQ(ini1+1,j+i-1)-D[ini1]+H[ini1];
      b=maxRMQ(ini2+1,j+i-1)-D[ini2]+H[ini2];
      c=maxRMQ(ini3+1,j+i-1)-D[ini3]+H[ini3];
      if (a>b){
        if (a>c){
          RMQ[j][p]=ini1;
        } else {
          RMQ[j][p]=ini3;
        }
      } else {
        if (b>c){
          RMQ[j][p]=ini2;
        } else {
          RMQ[j][p]=ini3;
        }
      }
    }
    p++;
  }
}

ll queryRMQ(int i,int f){
  ll a,b;
  int dis=log2(f-i+1);
  int ini1=RMQ[i][dis];
  int ini2=RMQ[f-(1<<dis)+1][dis];
  a=maxRMQ(ini1+1,f)-D[ini1]+H[ini1];
  b=maxRMQ(ini2+1,f)-D[ini2]+H[ini2];
  return max(a,b);
}

int main (){
  scanf("%d %d",&n,&m);
  int scan;
  for (int i=1;i<=n;i++){
    scanf("%d",&scan);
    D[i]=scan;
    D[i+n]=D[i];
    D[i]+=D[i-1];
  }
  for (int i=n+1;i<(n<<1);i++){
    D[i]+=D[i-1];
  }
  for (int i=0;i<n;i++){
    scanf("%d",&scan);
    H[i]=scan;
    H[i]*=2;
    H[i+n]=H[i];
  }
  for (int i=0;i<(n<<1);i++){
    A[i]=H[i]+D[i];
  }
  initMax();
  initRmq();
  for (int i=0;i<m;i++){
    int a,b,in,fn;
    scanf("%d %d",&a,&b);
    a--;
    b--;
    if (a<=b){
      in=b+1;
      fn=a+n-1;
    } else {
      in=b+1;
      fn=a-1;
    }
    ll ans=queryRMQ(in,fn);
    cout << ans << endl;
    if(ans == 391910){
      cout << a << " " << b << endl;
    }
  }
  return 0;
}


#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<string.h>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<bits/stdc++.h>
using namespace std;
const int inf = 1<<29;
const int mod = (int)1e9 + 7;
typedef long long ll;
int n,m,k;
ll d[200010], h[200010];
int ldp[200010][20], rdp[200010][20];
ll lsum[200010], rsum[200010];

void rmp_init()
{
    for(int i=1;i<=2*n;i++) ldp[i][0] = rdp[i][0] = i;
    for(int j=1;j<20;j++){
        for(int i=1;i + (1<<j) - 1 <= 2*n; i++){
            int l = i, r = i + (1<<j) - 1;
            int mid = r - (1<<(j-1)) + 1;
            {
                int lf = ldp[l][j-1], rt = ldp[mid][j-1];
                if(rsum[lf] + 2*h[lf] >= rsum[rt] + 2*h[rt]){
                    ldp[i][j] = lf;
                }
                else ldp[i][j] = rt;
            }
            {
                int lf = ldp[l][j-1], rt = ldp[mid][j-1];
                if(lsum[lf]-d[lf] + 2*h[lf] > lsum[rt]-d[rt] + 2*h[rt]){
                    rdp[i][j] = lf;
                }
                else rdp[i][j] = rt;
            }

        }
    }
//    for(int j=1;j<20;j++)
//        for(int i=1;i + (1<<j) - 1 <= 2*n; i++)
//            cout<<ldp[i][j]<<" "<<endl;
}

int rmp_l(int l, int r)
{
    if(l > r) return 0;
    int k = log2(r - l + 1);
    if(k == 0) return l;
    int mid = r - (1<<(k-1)) + 1;
    int lf = ldp[l][k-1], rt = ldp[mid][k-1];
    if(rsum[lf] + 2*h[lf] >= rsum[rt] + 2*h[rt]){
        return lf;
    }
    else return rt;
}

int rmp_r(int l, int r)
{
    if(l > r) return 0;
    int k = log2(r - l + 1);
    if(k == 0) return l;
    int mid = r - (1<<(k-1)) + 1;
    int lf = rdp[l][k-1], rt = rdp[mid][k-1];
    if(lsum[lf]-d[lf] + 2*h[lf] > lsum[rt]-d[rt] + 2*h[rt]){
        return lf;
    }
    else return rt;
}

ll solve(int l,int r)
{
//    cout<<"---"<<l<<" "<<r<<endl;
    ll ans1, ans2;
    int lf , rt;
    lf = rmp_l(l, r);
    rt = rmp_r(lf+1, r);
    if(rt != 0)
        ans1 = 2*(h[lf] + h[rt]) + lsum[rt-1] - lsum[lf-1];
    else ans1 = -1;
//    cout<<lf<<" "<<rt<<" "<<ans1<<endl;
    rt = rmp_r(l, r);
    lf = rmp_l(l, rt-1);
    if(lf != 0)
        ans2 = 2*(h[lf] + h[rt]) + lsum[rt-1] - lsum[lf-1];
    else ans2 = -1;
//    cout<<lf<<" "<<rt<<" "<<ans2<<endl;
    return max(ans1, ans2);
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
    cin>>n>>m;
    for(int i=1;i<=n;i++) scanf("%I64d", &d[i]), d[i+n] = d[i];
    for(int i=1;i<=n;i++) scanf("%I64d", &h[i]), h[i+n] = h[i];
    for(int i=1;i<=2*n;i++) lsum[i] += d[i] + lsum[i-1];
    for(int i=2*n;i>=1;i--) rsum[i] += d[i] + rsum[i+1];
    int l, r;
//    for(int i=6;i<=10;i++){
//        for(int j=i+1;j<=10;j++){
//            cout<<i<<" "<<j<<" "<<lsum[j-1] - lsum[i-1] + 2*(h[i] +  h[j]) <<endl;
//        }
//    }
    rmp_init();
    while(m--){
        scanf("%d %d", &l, &r);
        if(l <= r) swap(l, r),l++, r += n-1;
        else swap(l,r), l++, r--;
        printf("%I64d\n", solve(l, r));
    }
	return 0;
}


#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<string.h>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<bits/stdc++.h>
using namespace std;
const int inf = 1<<29;
const int mod = (int)1e9 + 7;
typedef long long ll;
int n,m,k;
ll d[200010], h[200010];
int ldp[200010][20], rdp[200010][20];
ll lsum[200010], rsum[200010];

void rmp_init()
{
    for(int i=1;i<=2*n;i++) ldp[i][0] = rdp[i][0] = i;
    for(int j=1;j<20;j++){
        for(int i=1;i + (1<<j) - 1 <= 2*n; i++){
            int l = i, r = i + (1<<j) - 1;
            int mid = r - (1<<(j-1)) + 1;
            {
                int lf = ldp[l][j-1], rt = ldp[mid][j-1];
                if(rsum[lf] + 2*h[lf] >= rsum[rt] + 2*h[rt]){
                    ldp[i][j] = lf;
                }
                else ldp[i][j] = rt;
            }
            {
                int lf = ldp[l][j-1], rt = ldp[mid][j-1];
                if(lsum[lf]-d[lf] + 2*h[lf] > lsum[rt]-d[rt] + 2*h[rt]){
                    rdp[i][j] = lf;
                }
                else rdp[i][j] = rt;
            }

        }
    }
//    for(int j=1;j<20;j++)
//        for(int i=1;i + (1<<j) - 1 <= 2*n; i++)
//            cout<<ldp[i][j]<<" "<<endl;
}

int rmp_l(int l, int r)
{
    if(l > r) return 0;
    int k = log2(r - l + 1);
    if(k == 0) return l;
    int mid = r - (1<<(k-1)) + 1;
    int lf = ldp[l][k-1], rt = ldp[mid][k-1];
    if(rsum[lf] + 2*h[lf] >= rsum[rt] + 2*h[rt]){
        return lf;
    }
    else return rt;
}

int rmp_r(int l, int r)
{
    if(l > r) return 0;
    int k = log2(r - l + 1);
    if(k == 0) return l;
    int mid = r - (1<<(k-1)) + 1;
    int lf = ldp[l][k-1], rt = ldp[mid][k-1];
    if(lsum[lf]-d[lf] + 2*h[lf] > lsum[rt]-d[rt] + 2*h[rt]){
        return lf;
    }
    else return rt;
}

ll solve(int l,int r)
{
    //cout<<"---"<<l<<" "<<r<<endl;
    ll ans1, ans2;
    int lf , rt;
    lf = rmp_l(l, r);
    rt = rmp_r(lf+1, r);
    if(rt != 0)
        ans1 = 2*(h[lf] + h[rt]) + lsum[rt-1] - lsum[lf-1];
    else ans1 = -1;
   // cout<<lf<<" "<<rt<<" "<<ans1<<endl;
    rt = rmp_r(l, r);
    lf = rmp_l(l, rt-1);
    if(lf != 0)
        ans2 = 2*(h[lf] + h[rt]) + lsum[rt-1] - lsum[lf-1];
    else ans2 = -1;
    //cout<<lf<<" "<<rt<<" "<<ans2<<endl;
    return max(ans1, ans2);
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
    cin>>n>>m;
    for(int i=1;i<=n;i++) scanf("%I64d", &d[i]), d[i+n] = d[i];
    for(int i=1;i<=n;i++) scanf("%I64d", &h[i]), h[i+n] = h[i];
    for(int i=1;i<=2*n;i++) lsum[i] += d[i] + lsum[i-1];
    for(int i=2*n;i>=1;i--) rsum[i] += d[i] + rsum[i+1];
    int l, r;
    rmp_init();
    while(m--){
        scanf("%d %d", &l, &r);
        if(l <= r) swap(l, r),l++, r += n-1;
        else swap(l,r), l++, r--;
        printf("%I64d\n", solve(l, r));
    }
	return 0;
}


#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<string.h>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<bits/stdc++.h>
using namespace std;
const int inf = 1<<29;
const int mod = (int)1e9 + 7;
typedef long long ll;
int n,m,k;
ll d[200010], h[200010];
int ldp[200010][20], rdp[200010][20];
ll lsum[200010], rsum[200010];

void rmp_init()
{
    for(int i=1;i<=2*n;i++) ldp[i][0] = rdp[i][0] = i;
    for(int j=1;j<20;j++){
        for(int i=1;i + (1<<j) - 1 <= 2*n; i++){
            int l = i, r = i + (1<<j) - 1;
            int mid = r - (1<<(j-1)) + 1;
            {
                int lf = ldp[l][j-1], rt = ldp[mid][j-1];
                if(rsum[lf] + 2*h[lf] >= rsum[rt] + 2*h[rt]){
                    ldp[i][j] = lf;
                }
                else ldp[i][j] = rt;
            }
            {
                int lf = rdp[l][j-1], rt = rdp[mid][j-1];
                if(lsum[lf]-d[lf] + 2*h[lf] > lsum[rt]-d[rt] + 2*h[rt]){
                    rdp[i][j] = lf;
                }
                else rdp[i][j] = rt;
            }

        }
    }
//    for(int j=1;j<20;j++)
//        for(int i=1;i + (1<<j) - 1 <= 2*n; i++)
//            cout<<ldp[i][j]<<" "<<endl;
}

int rmp_l(int l, int r)
{
    if(l > r) return 0;
    int k = log2(r - l + 1);
    if(k == 0) return l;
    int mid = r - (1<<k) + 1;
    int lf = ldp[l][k], rt = ldp[mid][k];
    if(rsum[lf] + 2*h[lf] >= rsum[rt] + 2*h[rt]){
        return lf;
    }
    else return rt;
}

int rmp_r(int l, int r)
{
    if(l > r) return 0;
    int k = log2(r - l + 1);
    if(k == 0) return l;
    int mid = r - (1<<k) + 1;
    int lf = rdp[l][k], rt = rdp[mid][k];
    if(lsum[lf]-d[lf] + 2*h[lf] > lsum[rt]-d[rt] + 2*h[rt]){
        return lf;
    }
    else return rt;
}

ll solve(int l,int r)
{
//    cout<<"---"<<l<<" "<<r<<endl;
    ll ans1, ans2;
    int lf , rt;
    lf = rmp_l(l, r);
    rt = rmp_r(lf+1, r);
    if(rt != 0)
        ans1 = 2*(h[lf] + h[rt]) + lsum[rt-1] - lsum[lf-1];
    else ans1 = -1;
//    cout<<lf<<" "<<rt<<" "<<ans1<<endl;
    rt = rmp_r(l, r);
    lf = rmp_l(l, rt-1);
    if(lf != 0)
        ans2 = 2*(h[lf] + h[rt]) + lsum[rt-1] - lsum[lf-1];
    else ans2 = -1;
//    cout<<lf<<" "<<rt<<" "<<ans2<<endl;
    return max(ans1, ans2);
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
    cin>>n>>m;
    for(int i=1;i<=n;i++) scanf("%I64d", &d[i]), d[i+n] = d[i];
    for(int i=1;i<=n;i++) scanf("%I64d", &h[i]), h[i+n] = h[i];
    for(int i=1;i<=2*n;i++) lsum[i] += d[i] + lsum[i-1];
    for(int i=2*n;i>=1;i--) rsum[i] += d[i] + rsum[i+1];
    int l, r;
//    for(int i=6;i<=10;i++){
//        for(int j=i+1;j<=10;j++){
//            cout<<i<<" "<<j<<" "<<lsum[j-1] - lsum[i-1] + 2*(h[i] +  h[j]) <<endl;
//        }
//    }
    rmp_init();
    while(m--){
        scanf("%d %d", &l, &r);
        if(l <= r) swap(l, r),l++, r += n-1;
        else swap(l,r), l++, r--;
        printf("%I64d\n", solve(l, r));
    }
	return 0;
}


// Aditya Shah

#include <bits/stdc++.h>

using namespace std;

#define V vector

typedef long long LL;
typedef pair<int, int> pii;

typedef V<int> vi;
typedef V<string> vs;
typedef V<LL> vl;
typedef V<double> vd;
typedef V<pii> vpii;

#define forup(i,a,b) for(int i=(a); i<(b); ++i)
#define fordn(i,a,b) for(int i=(a); i>(b); --i)
#define rep(i,a) for(int i=0; i<(a); ++i)
#define fov(i,a) rep(i,(a).size())
#define foreach(i,X) for(__typeof((X).begin()) i = (X).begin(); i != (X).end(); i++)

#define gi(x) scanf("%d",&x)
#define gd(x) scanf("%lf",&x)
#define gs(x) cin >> x

#define pi(x) printf("%d",x)
#define pin(x) printf("%d\n",x)
#define ps(s) cout << s;
#define psn(s) cout << s << "\n"
#define pn printf("\n")
#define spc printf(" ")
#define prec(x) cout<<fixed<<setprecision(x)

#define all(x) (x).begin(), (x).end()

#define fs first
#define sc second

#define pb push_back
#define mp make_pair

#define fr freopen("input.in", "r", stdin)
#define fw freopen("output.out", "w", stdout)

#define FastIO ios_base::sync_with_stdio(0); \
        cin.tie(0);

#define SET(a, v) memset(a, v, sizeof a)

const int inf = numeric_limits<int>::max();
const LL linf = numeric_limits<LL>::max() / 10;
const int maxn = 200005;

double EPS = 1e-12;
double PI = 2 * acos(0);

struct DP {
    LL MaxA, MaxB, Best;
    DP(LL A, LL B, LL best) {
        MaxA = A; MaxB = B; Best = best;
    }
    DP() {}
};

LL d[maxn], h[maxn], A[maxn], B[maxn];
DP tree[maxn << 2];

DP MAX(DP X, DP Y) {
    return DP(max(X.MaxA, Y.MaxA), max(X.MaxB, Y.MaxB), max(X.Best, Y.Best));
}

void build(int L, int R, int I) {
    if (L == R) {
        tree[I] = DP(A[L], B[L], 0);
        return;
    }
    int l = (I << 1), r = (I << 1) | 1, mid = (L + R) >> 1;
    build(L, mid, l);
    build(mid + 1, R, r);
    tree[I] = MAX(tree[l], tree[r]);
    tree[I].Best = max(tree[I].Best, tree[r].MaxB + tree[l].MaxA);
}

DP Garb = DP(-linf, -linf, -linf);

DP Query(int L, int R, int I, int X, int Y) {
    if (Y < L || X > R) return Garb;
    if (L >= X && R <= Y) return tree[I];
    int l = (I << 1), r = (I << 1) | 1, mid = (L + R) >> 1;
    DP Left = Query(L, mid, l, X, Y);
    DP Right = Query(mid + 1, R, r, X, Y);
    DP res = MAX(Left, Right);
    res.Best = max(res.Best, Right.MaxB + Left.MaxA);
    return res;
}

int main() {
    int N, M, D, x, y;
    gi(N); gi(M);
    forup(i, 1, N + 1) { gi(D); d[i] = D;}
    forup(i, 1, N + 1) { gi(D); h[i] = D;}
    forup(i, N + 1, N + N + 1) {
        d[i] = d[i - N];
        h[i] = h[i - N];
    }
    N <<= 1;
    forup(i, 1, N + 1) {
        d[i] += d[i - 1];
        A[i] = (h[i] * 2) - d[i - 1];
        B[i] = (h[i] * 2) + d[i - 1];
    }
    build(1, N, 1);
    while (M--) {
        gi(x); gi(y);
        if (x <= y) {
            int f = y + 1;
            y = x + N / 2 - 1;
            x = f;
        } else {
            ++x; --y;
        }
        printf("%I64d\n", (Query(1, N, 1, x, y).Best));
    }
    return 0;
}


// Aditya Shah

#include <bits/stdc++.h>

using namespace std;

#define V vector

typedef long long LL;
typedef pair<int, int> pii;

typedef V<int> vi;
typedef V<string> vs;
typedef V<LL> vl;
typedef V<double> vd;
typedef V<pii> vpii;

#define forup(i,a,b) for(int i=(a); i<(b); ++i)
#define fordn(i,a,b) for(int i=(a); i>(b); --i)
#define rep(i,a) for(int i=0; i<(a); ++i)
#define fov(i,a) rep(i,(a).size())
#define foreach(i,X) for(__typeof((X).begin()) i = (X).begin(); i != (X).end(); i++)

#define gi(x) scanf("%d",&x)
#define gd(x) scanf("%lf",&x)
#define gl(x) scanf("%I64d", &x)
#define gs(x) cin >> x

#define pi(x) printf("%d",x)
#define pin(x) printf("%d\n",x)
#define ps(s) cout << s;
#define psn(s) cout << s << "\n"
#define pn printf("\n")
#define spc printf(" ")
#define prec(x) cout<<fixed<<setprecision(x)

#define all(x) (x).begin(), (x).end()

#define fs first
#define sc second

#define pb push_back
#define mp make_pair

#define fr freopen("input.in", "r", stdin)
#define fw freopen("output.out", "w", stdout)

#define FastIO ios_base::sync_with_stdio(0); \
        cin.tie(0);

#define SET(a, v) memset(a, v, sizeof a)

const int inf = numeric_limits<int>::max();
const LL linf = numeric_limits<LL>::max() / 10;
const int maxn = 200005;

double EPS = 1e-12;
double PI = 2 * acos(0);

struct DP {
    LL MaxA, MaxB, Best;
    DP(LL A, LL B, LL best) {
        MaxA = A; MaxB = B; Best = best;
    }
    DP() {}
};

LL d[maxn], h[maxn], A[maxn], B[maxn];
DP tree[maxn << 2];

DP MAX(DP X, DP Y) {
    return DP(max(X.MaxA, Y.MaxA), max(X.MaxB, Y.MaxB), max(X.Best, Y.Best));
}

void build(int L, int R, int I) {
    if (L == R) {
        tree[I] = DP(A[L], B[L], 0);
        return;
    }
    int l = (I << 1), r = (I << 1) | 1, mid = (L + R) >> 1;
    build(L, mid, l);
    build(mid + 1, R, r);
    tree[I] = MAX(tree[l], tree[r]);
    tree[I].Best = max(tree[I].Best, tree[r].MaxB + tree[l].MaxA);
}

DP Garb = DP(-linf, -linf, -linf);

DP Query(int L, int R, int I, int X, int Y) {
    if (Y < L || X > R) return Garb;
    if (L >= X && R <= Y) return tree[I];
    int l = (I << 1), r = (I << 1) | 1, mid = (L + R) >> 1;
    DP Left = Query(L, mid, l, X, Y);
    DP Right = Query(mid + 1, R, r, X, Y);
    DP res = MAX(Left, Right);
    res.Best = max(res.Best, Right.MaxB + Left.MaxA);
    return res;
}

int main() {
    int N, M, D, x, y;
    gi(N); gi(M);
    forup(i, 1, N + 1) gl(d[i]);
    forup(i, 1, N + 1) gl(h[i]);
    forup(i, N + 1, N + N + 1) {
        d[i] = d[i - N];
        h[i] = h[i - N];
    }
    N <<= 1;
    forup(i, 1, N + 1) {
        d[i] += d[i - 1];
        A[i] = (h[i] * 2) - d[i - 1];
        B[i] = (h[i] * 2) + d[i - 1];
    }
    build(1, N, 1);
    while (M--) {
        gi(x); gi(y);
        if (x <= y) {
            int f = y + 1;
            y = x + N / 2 - 1;
            x = f;
        } else {
            --x; ++y;
            swap(x, y);
        }
        printf("%I64d\n", (Query(1, N, 1, x, y).Best));
    }
    return 0;
}


#include <cstdio>
#include <cctype>
#include <algorithm>
#define ll long long
#define inf 10000000000000000

using namespace std;

inline ll read(){
	ll x=0,w=0;char ch=getchar();
	while (!isdigit(ch))w|=ch=='-',ch=getchar();
	while (isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
	return w?-x:x;
}

struct node{
	ll two_val, l_val, r_val, no_val;
}a[8000005];

ll n, m, h[800005], dis[800005], two_ans, l_ans, r_ans, no_ans;

inline ll ls(ll p){
	return p << 1;
}

inline ll rs(ll p){
	return p << 1 | 1;
}

inline void update(int p){
	a[p].two_val = max(a[ls(p)].l_val + a[rs(p)].r_val, max(a[ls(p)].two_val , a[rs(p)].two_val ));
	a[p].l_val = max(a[ls(p)].l_val + a[rs(p)].no_val, a[rs(p)].l_val ) ;
	a[p].r_val = max(a[ls(p)].no_val + a[rs(p)].r_val, a[ls(p)].r_val ) ;
	a[p].no_val = a[ls(p)].no_val + a[rs(p)].no_val ;
}

inline void build(ll p, ll l, ll r){
	if(l == r){
//		a[p].two_val = h[l] + dis[l];
		a[p].l_val = h[l] + dis[l];
		a[p].r_val = h[l] + dis[l];
		a[p].no_val = dis[l];
//		printf("%lld %lld %lld\n",l, r, a[p].two_val );
		return ;
	}
	ll mid = l + r >> 1;
	build(ls(p), l, mid);
	build(rs(p), mid + 1, r);
	update(p);
//	if(l & 1 && r & 1){
//		printf("%lld %lld %lld %lld %lld %lld\n",l, r, a[p].no_val , a[p].l_val , a[p].r_val , a[p].two_val );
//	}
}

inline ll query(ll p, ll l, ll r, ll L, ll R){
	if(L <= l && r <= R){
		two_ans = max(two_ans, max(a[p].two_val , l_ans + a[p].r_val ));
		l_ans = max(l_ans + a[p].no_val , max(a[p].l_val , l_ans));
		return 0;
	}
	ll mid = l + r >> 1;
	if(mid >= L) query(ls(p), l, mid, L, R);
	if(mid < R) query(rs(p), mid + 1, r, L, R);
}

int main(){
	n = read();
	m = read();
	for(int i = 2; i <= 2 * n; i += 2)
	dis[i] = read(), dis[i - 1] = 0;
	for(int i = 1; i <= 2 * n; i += 2)
	h[i] = read() * 2, h[i + 1] = -inf;
	for(int i = 1; i <= 2 * n; i++)
	dis[2 * n + i] = dis[i], h[i + 2 * n] = h[i];
	build(1, 1, 4 * n - 1);
	for(int i = 1; i <= m; i++){
		ll x = read(), y = read();
		two_ans = l_ans = -inf;
		if(x == y){
			query(1, 1, 4 * n - 1, 2 * x + 1, 2 * x - 3 + 2 * n);
		}
		else if(x < y){
			query(1, 1, 4 * n - 1, 2 * y + 1, 2 * x - 3 + 2 * n);
		}
		else {
			query(1 , 1, 4 * n - 1, 2 * y + 1, 2 * x - 3);
		}
		printf("%lld\n",two_ans);
	}
    return 0;
}


#include <cstdio>
#include <cctype>
#include <algorithm>
#define ll long long
#define inf 10000000000000000

using namespace std;

inline ll read(){
	int x=0,w=0;char ch=getchar();
	while (!isdigit(ch))w|=ch=='-',ch=getchar();
	while (isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
	return w?-x:x;
}

struct node{
	ll two_val, l_val, r_val, no_val;
}a[4000005];

ll n, m, h[200005], dis[200005], two_ans, l_ans, r_ans, no_ans;

inline ll ls(ll p){
	return p << 1;
}

inline ll rs(ll p){
	return p << 1 | 1;
}

inline void update(int p){
	a[p].two_val = max(a[ls(p)].l_val + a[rs(p)].r_val, max(a[ls(p)].two_val , a[rs(p)].two_val ));
	a[p].l_val = max(a[ls(p)].l_val + a[rs(p)].no_val, a[rs(p)].l_val ) ;
	a[p].r_val = max(a[ls(p)].no_val + a[rs(p)].r_val, a[ls(p)].r_val ) ;
	a[p].no_val = a[ls(p)].no_val + a[rs(p)].no_val ;
}

inline void build(ll p, ll l, ll r){
	if(l == r){
//		a[p].two_val = h[l] + dis[l];
		a[p].l_val = h[l] + dis[l];
		a[p].r_val = h[l] + dis[l];
		a[p].no_val = dis[l];
//		printf("%lld %lld %lld\n",l, r, a[p].two_val );
		return ;
	}
	ll mid = l + r >> 1;
	build(ls(p), l, mid);
	build(rs(p), mid + 1, r);
	update(p);
//	if(l & 1 && r & 1){
//		printf("%lld %lld %lld %lld %lld %lld\n",l, r, a[p].no_val , a[p].l_val , a[p].r_val , a[p].two_val );
//	}
}

inline ll query(ll p, ll l, ll r, ll L, ll R){
	if(L <= l && r <= R){
		two_ans = max(two_ans, max(a[p].two_val , l_ans + a[p].r_val ));
		l_ans = max(l_ans + a[p].no_val , max(a[p].l_val , l_ans));
		return 0;
	}
	ll mid = l + r >> 1;
	if(mid >= L) query(ls(p), l, mid, L, R);
	if(mid < R) query(rs(p), mid + 1, r, L, R);
}

int main(){
	n = read();
	m = read();
	for(int i = 2; i <= 2 * n; i += 2)
	dis[i] = read(), dis[i - 1] = 0;
	for(int i = 1; i <= 2 * n; i += 2)
	h[i] = read() * 2, h[i + 1] = -inf;
	for(int i = 1; i <= 2 * n; i++)
	dis[2 * n + i] = dis[i], h[i + 2 * n] = h[i];
	build(1, 1, 4 * n - 1);
	for(int i = 1; i <= m; i++){
		ll x = read(), y = read();
		two_ans = l_ans = r_ans = no_ans = -inf;
		if(x == y){
			query(1, 1, 4 * n - 1, 2 * x + 1, 2 * x - 3 + 2 * n);
		}
		else if(x < y){
			query(1, 1, 4 * n - 1, 2 * y + 1, 2 * x - 3 + 2 * n);
		}
		else {
			query(1 , 1, 4 * n - 1, 2 * y + 1, 2 * x - 3);
		}
		printf("%lld\n",two_ans);
	}
    return 0;
}


#include <cstdio>
#include <cctype>
#include <algorithm>
#define ll long long
#define inf 10000000000000000

using namespace std;

inline ll read(){
	int x=0,w=0;char ch=getchar();
	while (!isdigit(ch))w|=ch=='-',ch=getchar();
	while (isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
	return w?-x:x;
}

struct node{
	ll two_val, l_val, r_val, no_val;
}a[4000005];

ll n, m, h[200005], dis[200005], two_ans, l_ans, r_ans, no_ans;

inline ll ls(ll p){
	return p << 1;
}

inline ll rs(ll p){
	return p << 1 | 1;
}

inline void update(int p){
	a[p].two_val = max(a[ls(p)].l_val + a[rs(p)].r_val, max(a[ls(p)].two_val , a[rs(p)].two_val ));
	a[p].l_val = a[ls(p)].l_val + a[rs(p)].no_val ;
	a[p].r_val = a[ls(p)].no_val + a[rs(p)].r_val ;
	a[p].no_val = a[ls(p)].no_val + a[rs(p)].no_val ;
}

inline void build(ll p, ll l, ll r){
	if(l == r){
//		a[p].two_val = 2 * h[l] + dis[l];
		a[p].l_val = h[l] + dis[l];
		a[p].r_val = h[l] + dis[l];
		a[p].no_val = dis[l];
//		printf("%lld %lld %lld\n",l, r, a[p].two_val );
		return ;
	}
	ll mid = l + r >> 1;
	build(ls(p), l, mid);
	build(rs(p), mid + 1, r);
	update(p);
//	if(l & 1 && r & 1){
//		printf("%lld %lld %lld\n",l, r, a[p].two_val );
//	}
}

inline ll query(ll p, ll l, ll r, ll L, ll R){
	if(L <= l && r <= R){
		two_ans = max(two_ans, max(a[p].two_val , l_ans + a[p].r_val ));
		l_ans = max(l_ans + a[p].no_val , a[p].l_val );
		return 0;
	}
	ll mid = l + r >> 1;
	if(mid >= L) query(ls(p), l, mid, L, R);
	if(mid < R) query(rs(p), mid + 1, r, L, R);
}

int main(){
	n = read();
	m = read();
	for(int i = 2; i <= 2 * n; i += 2)
	dis[i] = read(), dis[i - 1] = 0;
	for(int i = 1; i <= 2 * n; i += 2)
	h[i] = read() * 2, h[i + 1] = -inf;
	for(int i = 1; i <= 2 * n; i += 2)
	dis[2 * n + i + 1] = dis[i + 1], h[i + 2 * n] = h[i];
	build(1, 1, 4 * n);
	for(int i = 1; i <= m; i++){
		ll x = read(), y = read();
		two_ans = l_ans = r_ans = no_ans = 0;
		if(x == y){
			query(1, 1, 4 * n, 2 * x + 1, 2 * x - 3 + 2 * n);
		}
		else if(x < y){
			query(1, 1, 4 * n, 2 * y + 1, 2 * x - 3 + 2 * n);
		}
		else {
			query(1 , 1, 4 * n, 2 * x + 1, 2 * y - 3 + 2 * n);
		}
		printf("%lld\n",two_ans);
	}
    return 0;
}


#include<bits/stdc++.h>
#define maxn 200003
#define INF 100000000000000000ll
using namespace std;
struct node{
	long long lmx,rmx,mx,lr,rr,r;
	node():lmx(0),rmx(0),mx(0),lr(0),rr(0),r(0){}
}t[maxn<<2];
int n,d[maxn],h[maxn],m;
void pushup(node& t1,const node& t2,const node& t3,int mid){
	t1.lmx=max(t2.lmx,t3.lmx+t2.mx+d[mid]);
	t1.rmx=max(t3.rmx,t2.rmx+t3.mx+d[mid]);
	t1.mx=max(max(t2.mx,t3.mx),t2.rmx+t3.lmx+d[mid]);
	t1.lr=max(t2.lr,t3.lr+t2.mx+d[mid]);
	t1.rr=max(t3.rr,t2.rr+t3.mx+d[mid]);
	t1.r=max(max(t2.r,t3.r),t2.rr+t3.lr+d[mid]);
}
void build(int p,int l,int r){
	if(l==r){
		t[p].lmx=t[p].rmx=t[p].mx=0;
		t[p].lr=t[p].rr=t[p].r=2ll*h[l];
		return;
	}
	int mid=(l+r)>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	pushup(t[p],t[p<<1],t[p<<1|1],mid);
}
node query(int p,int l,int r,int seg_l,int seg_r){
	if(seg_l<=l&&r<=seg_r){
		return t[p];
	}
	int mid=(l+r)>>1;
	node tmp1,tmp2,ret;
	if(seg_l<=mid&&seg_r>mid){
		tmp1=query(p<<1,l,mid,seg_l,seg_r);
		tmp2=query(p<<1|1,mid+1,r,seg_l,seg_r);
		pushup(ret,tmp1,tmp2,mid);
	}
	else if(seg_l<=mid)ret=query(p<<1,l,mid,seg_l,seg_r);
	else if(seg_r>mid)ret=query(p<<1|1,mid+1,r,seg_l,seg_r);
	return ret;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d",d+i),d[i+n]=d[i];
	for(int i=1;i<=n;i++)scanf("%d",h+i),h[i+n]=h[i];
	build(1,1,n+n);
	while(m--){
		int a,b;
		scanf("%d%d",&a,&b);
		if(a<=b){
			a+=n-1;
			b++;
		}
		else{
			a++;
			b--;
		}
		node tmp=query(1,1,n+n,b,a);
		cout<<tmp.r<<endl;
	}
	return 0;
}


#include<bits/stdc++.h>
#define maxn 200003
#define INF 100000000000000000ll
using namespace std;
struct node{
	long long lmx,rmx,mx,lr,rr,r;
	node():lmx(0),rmx(0),mx(0),lr(0),rr(0),r(0){}
}t[maxn<<2];
int n,d[maxn],h[maxn],m;
void pushup(node& t1,const node& t2,const node& t3,int mid){
	t1.lmx=max(t2.lmx,t3.lmx+t2.mx+d[mid]);
	t1.rmx=max(t3.rmx,t2.rmx+t3.mx+d[mid]);
	t1.mx=max(max(t2.mx,t3.mx),t2.rmx+t3.lmx+d[mid]);
	t1.lr=max(t2.lr,t3.lr+t2.mx+d[mid]);
	t1.rr=max(t3.rr,t2.rr+t3.mx+d[mid]);
	t1.r=max(max(t2.r,t3.r),t2.rr+t3.lr+d[mid]);
}
void build(int p,int l,int r){
	if(l==r){
		t[p].lmx=t[p].rmx=t[p].mx=0;
		t[p].lr=t[p].rr=t[p].r=2ll*h[l];
		return;
	}
	int mid=(l+r)>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	pushup(t[p],t[p<<1],t[p<<1|1],mid);
}
node query(int p,int l,int r,int seg_l,int seg_r){
	if(seg_l<=l&&r<=seg_r){
		return t[p];
	}
	int mid=(l+r)>>1;
	node tmp1,tmp2,ret;
	if(seg_l<=mid&&seg_r>mid){
		tmp1=query(p<<1,l,mid,seg_l,seg_r);
		tmp2=query(p<<1|1,mid+1,r,seg_l,seg_r);
		pushup(ret,tmp1,tmp2,mid);
	}
	else if(seg_l<=mid)ret=query(p<<1,l,mid,seg_l,seg_r);
	else if(seg_r>mid)ret=query(p<<1|1,mid+1,r,seg_l,seg_r);
	return ret;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d",d+i),d[i+n]=d[i];
	for(int i=1;i<=n;i++)scanf("%d",h+i),h[i+n]=h[i];
	build(1,1,n+n);
	while(m--){
		int a,b;
		scanf("%d%d",&a,&b);
		if(a<=b){
			a+=n-1;
			b++;
		}
		else{
			a--;
			b++;
		}
		node tmp=query(1,1,n+n,b,a);
		cout<<tmp.r<<endl;
	}
	return 0;
}


#include <bits/stdc++.h>
#define int long long
using std::cin;
using std::cout;

const int N = 200007;
struct segment {
	int a, b, max;
	void mem() {
		a = b = max = -1e18;
	}
}T[N << 2];

int n, m, d[N << 1], h[N << 1];

#define ls rt << 1
#define rs rt << 1 | 1

void update(int rt) {
	T[rt].a = std::max(T[ls].a, T[rs].a);
	T[rt].b = std::max(T[ls].b, T[rs].b);
	T[rt].max = std::max(T[ls].max, std::max(T[rs].max, T[ls].b + T[rs].a));
}

void build(int rt, int l, int r) {
	if (l == r) {
		T[rt].a = h[l] + d[l - 1];
		T[rt].b = h[l] - d[l - 1];
		T[rt].max = -1e18;
		return;
	}
	int mid = l + r >> 1;
	build(ls, l, mid);
	build(rs, mid + 1, r);
	update(rt);
}

segment query(int rt, int l, int r, int L, int R) {
	if (L <= l && r <= R) {
		return T[rt];
	}
	int mid = l + r >> 1;
	segment p, q, o;
	p.mem();q.mem();o.mem();
	if (L <= mid) p = query(ls, l, mid, L, R);
	if (R > mid) q = query(rs, mid + 1, r, L, R);
	o.a = std::max(p.a, q.a);
	o.b = std::max(p.b, q.b);
	o.max = std::max(p.max, std::max(q.max, p.b + q.a));
	return o;
}

signed main() {
	std::ios::sync_with_stdio(0);
	cin >> n >> m;
	for (int i = 1; i <= n; ++ i) {
		cin >> d[i];
		d[i + n] = d[i];
	}
	for (int i = 1; i <= (n << 1); ++ i) d[i] += d[i - 1];
	for (int i = 1; i <= n; ++ i) {
		cin >> h[i];
		h[i] <<= 1;
		h[i + n] = h[i];
	}
	n <<= 1;
	build(1, 1, n);
	while (m--) {
		int x, y;
		cin >> x >> y;
		if (x <= y) cout << query(1, 1, n, y + 1, x + (n >> 1) - 1).max << '\n';
		else cout << query(1, 1, n, y + 1, x - 1).max << '\n';
	}
	return 0;
}


    #include "bits/stdc++.h"
    using namespace std;

    #define ll long long int
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define pll pair<ll,ll>
    #define inf 1000000000000000

    const int MAXN = 300005;

    pll Tree1[4*MAXN], Tree2[4*MAXN];
    ll val1[MAXN], val2[MAXN];
    ll d[MAXN],H[MAXN],N,M;

    inline pll merge(pll a, pll b) {
    	if(a.first>=b.first) return a;
    	return b;
    }

    void build(ll node, ll start, ll end) {
    	if(start==end) {
    		Tree1[node] = mp(val1[start],start);
    		Tree2[node] = mp(val2[start],start);
    	} else {
    		ll mid = (start+end)/2;
    		build(2*node,start,mid);
    		build(2*node+1,mid+1,end);

    		Tree1[node] = merge(Tree1[2*node],Tree1[2*node+1]);
    		Tree2[node] = merge(Tree2[2*node],Tree2[2*node+1]);
    	}
    }

    pll query(ll node, ll start, ll end, ll l, ll r, ll k) {
    	if(start>end || l>end || r<start) return mp(-inf,0);

    	if(l<=start && end<=r) {
    		return k?Tree1[node]:Tree2[node];
    	}

    	ll mid = (start+end)/2;

    	pll left = mp(-inf,0), right = mp(-inf,0);
    	if(l<=mid) left = query(2*node,start,mid,l,r,k);
    	if(mid+1<=r) right =query(2*node+1,mid+1,end,l,r,k);

    	return merge(left,right);
    }

    int main() {
    	ios_base::sync_with_stdio(false);
    	cin.tie(0);cout.tie(0);

    	cin>>N>>M;

    	d[0]=0,H[0]=0;
    	for(int i=1;i<=N;i++) {
    		cin>>d[i];
    		d[i+N] = d[i];
    	}

    	for(int i=1;i<=N;i++) {
    		cin>>H[i];
    		H[i+N] = H[i];
    	}

    	for(int i=1;i<=2*N;i++) {
    		d[i] += d[i-1];
    		val1[i] = 2*H[i]+d[i-1];
    		val1[i+N] = val1[i];
    		val2[i] = 2*H[i] - d[i-1];
    		val2[i+N] = val2[i];
    	}

    	build(1,1,2*N);

    	ll a,b,u,v;
    	pll p1,p2,p3,p4;
    	while(M--) {
    		cin>>a>>b;

    		if(a<=b) {
    			u = b+1, v = a+N-1;
    		} else {
    			u = b+1, v = a-1;
    		}

    		p1 = query(1,1,2*N,u,v,1);
    		p2 = merge(query(1,1,2*N,u,p1.second-1,0),query(1,1,2*N,p1.second+1,v,0));
    		//p3 = query(1,1,2*N,u,v,0);
    		//p4 = merge(query(1,1,2*N,u,p3.second-1,1),query(1,1,2*N,p3.second+1,v,1));
    		//cout<<max(p1.first+p2.first,p3.first+p4.first)<<endl;
            cout<<p1.first+p2.first<<endl;
    	}

    }


    #include "bits/stdc++.h"
    using namespace std;

    #define ll long long int
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define pll pair<ll,ll>
    #define inf 1000000000000000

    const int MAXN = 300005;

    pll Tree1[4*MAXN], Tree2[4*MAXN];
    ll val1[MAXN], val2[MAXN];
    ll d[MAXN],H[MAXN],N,M;

    inline pll merge(pll a, pll b) {
    	if(a.first>=b.first) return a;
    	return b;
    }

    void build(ll node, ll start, ll end) {
    	if(start==end) {
    		Tree1[node] = mp(val1[start],start);
    		Tree2[node] = mp(val2[start],start);
    	} else {
    		ll mid = (start+end)/2;
    		build(2*node,start,mid);
    		build(2*node+1,mid+1,end);

    		Tree1[node] = merge(Tree1[2*node],Tree1[2*node+1]);
    		Tree2[node] = merge(Tree2[2*node],Tree2[2*node+1]);
    	}
    }

    pll query(ll node, ll start, ll end, ll l, ll r, ll k) {
    	if(start>end || l>end || r<start) return mp(-inf,0);

    	if(l<=start && end<=r) {
    		return k?Tree1[node]:Tree2[node];
    	}

    	ll mid = (start+end)/2;

    	pll left = mp(-inf,0), right = mp(-inf,0);
    	if(l<=mid) left = query(2*node,start,mid,l,r,k);
    	if(mid+1<=r) right =query(2*node+1,mid+1,end,l,r,k);

    	return merge(left,right);
    }

    int main() {
    	ios_base::sync_with_stdio(false);
    	cin.tie(0);cout.tie(0);

    	cin>>N>>M;

    	d[0]=0,H[0]=0;
    	for(int i=1;i<=N;i++) {
    		cin>>d[i];
    		d[i+N] = d[i];
    	}

    	for(int i=1;i<=N;i++) {
    		cin>>H[i];
    		H[i+N] = H[i];
    	}

    	for(int i=1;i<=2*N;i++) {
    		d[i] += d[i-1];
    		val1[i] = 2*H[i]+d[i-1];
    		val1[i+N] = val1[i];
    		val2[i] = 2*H[i] - d[i-1];
    		val2[i+N] = val2[i];
    	}

    	build(1,1,2*N);

    	ll a,b,u,v;
    	pll p1,p2,p3,p4;
    	while(M--) {
    		cin>>a>>b;

    		if(a<=b) {
    			u = b+1, v = a+N-1;
    		} else {
    			u = b+1, v = a-1;
    		}

    		p1 = query(1,1,2*N,u,v,1);
    		p2 = merge(query(1,1,2*N,u,p1.second-1,0),query(1,1,2*N,p1.second+1,v,0));
    		p3 = query(1,1,2*N,u,v,0);
    		p4 = merge(query(1,1,2*N,u,p3.second-1,1),query(1,1,2*N,p3.second+1,v,1));
    		cout<<max(p1.first+p2.first,p3.first+p4.first)<<endl;
            //cout<<p1.first+p2.first<<endl;
    	}

    }


#include <bits/stdc++.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, N) for (int I = 0; I < (N); ++I)
#define REPP(I, A, B) for (int I = (A); I < (B); ++I)
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define RS(X) scanf("%s", (X))
#define CASET int ___T, case_n = 1; scanf("%d ", &___T); while (___T-- > 0)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define PLL pair<long long,long long>
#define F first
#define S second
typedef long long LL;
using namespace std;
const int SIZE = 4e5+10;
int d[SIZE],h[SIZE];
pair<LL,int> W[2][19][SIZE][2];
int two[SIZE];
pair<LL,int> INF=MP(-1e18,-1);
void fresh(pair<LL,int> target[],pair<LL,int> v){
    if(v.S==target[0].S||v.S==target[1].S)return;
    if(v.F>target[0].F){
        target[1]=target[0];
        target[0]=v;
    }
    else if(v.F>target[1].F){
        target[1]=v;
    }
}
LL query(int x,int y){
    pair<LL,int>res[2][2];
    int lv=two[y-x+1];
    REP(i,2){
        REP(j,2)res[i][j]=W[i][lv][x][j];
        REP(j,2)fresh(res[i],W[i][lv][y-(1<<lv)+1][j]);
    }
    if(res[0][0].S!=res[1][0].S)return res[0][0].F+res[1][0].F;
    return max(res[0][0].F+res[1][1].F,res[0][1].F+res[1][0].F);
}
int main(){
    REP(i,19)two[1<<i]=i;
    REPP(i,1,SIZE)
        if(!two[i])two[i]=two[i-1];
    DRII(n,m);
    REP(i,n){
        RI(d[i]);
        d[i+n]=d[i];
    }
    REP(i,n){
        RI(h[i]);
        h[i+n]=h[i];
    }
    LL now=0;
    REP(i,n*2){
        W[0][0][i][0]=MP(now+h[i]*2,i);
        W[1][0][i][0]=MP(-now+h[i]*2,i);
        W[0][0][i][1]=W[1][0][i][1]=INF;
        now+=d[i];
    }
    REP(j,2){
        REPP(i,1,19){
            REP(k,n*2){
                REP(k2,2)W[j][i][k][k2]=W[j][i-1][k][k2];
                if(k+(1<<(i-1))<n*2){
                    fresh(W[j][i][k],W[j][i-1][k+(1<<(i-1))][0]);
                    fresh(W[j][i][k],W[j][i-1][k+(1<<(i-1))][1]);
                }
            }
        }
    }
    while(m--){
        DRII(x,y);
        x--;y--;
        int rx=(y+1)%n;
        int ry=(x-1+n)%n;
        if(ry<rx)ry+=n;
        printf("%I64d\n",query(rx,ry));
    }
    return 0;
}


#include <bits/stdc++.h>

typedef long long ll;

using namespace std;

#define MAXN 100000

template<typename T> struct RMQ {

    int sz;
    function<T(T, T)> comb;
    vector<vector<T>> sparse;

    RMQ(function<T(T, T)> _comb, int _sz) : comb(_comb), sz(_sz) {
        int depth = 32 - __builtin_clz(sz);
        sparse = vector<vector<T>>(sz, vector<T>());
        for (int i = 0; i < sz; i++) { sparse[i].reserve(depth); }
    }

    void set(int idx, T v) {
        if (sparse[idx].empty()) {
            sparse[idx].push_back(v);
        } else {
            sparse[idx][0] = v;
        }
    }

    void build() {
        int depth = 32 - __builtin_clz(sz);
        for (int j = 1; j < depth; j++) {
            int shift = 1 << (j - 1);
            for (int i = 0; i < sz; i++) {
                sparse[i].push_back(comb(sparse[i][j - 1], sparse[max(0, i - shift)][j - 1]));
            }
        }
    }

    T query(int lo, int hi) {
        int len = (hi - lo + 1);
        int j = 31 - __builtin_clz(len);
        return comb(sparse[lo + (1 << j) - 1][j], sparse[hi][j]);
    }

};

struct data {
    ll v1;
    int idx1;
    ll v2;
    int idx2;
};

int n, m;
ll d[MAXN << 1], h[MAXN << 1];

data add(data a, ll v, int idx) {
    if (a.idx1 == idx || a.idx2 == idx) { return a; }
    if (v > a.v1) { return (data){ v, idx, a.v1, a.idx1 }; } else if (v > a.v2) { return (data){ a.v1, a.idx1, v, idx }; }
    return a;
}

data comb(data a, data b) {
    return add(add(a, b.v1, b.idx1), b.v2, b.idx2);
}

int main() {
    cin >> n >> m;
    for (int i = 0; i < n; i++) { cin >> d[(i + 1) % n]; }
    for (int i = 0; i < n; i++) { d[i + n] = d[i]; }
    for (int i = 1; i < 2 * n; i++) { d[i] += d[i - 1]; }
    for (int i = 0; i < n; i++) {
        cin >> h[i];
        h[i + n] = h[i];
    }
    RMQ<data> rmq1(comb, 2 * n), rmq2(comb, 2 * n);
    for (int i = 0; i < 2 * n; i++) {
        rmq1.set(i, (data){ 2 * h[i] + d[i], i, LLONG_MIN, -1 });
        rmq2.set(i, (data){ 2 * h[i] - d[i], i, LLONG_MIN, -1 });
    }
    rmq1.build();
    rmq2.build();
    for (int i = 0; i < m; i++) {
        int l, r;
        cin >> r >> l;
        r -= 2;
        while (r < l) { r += n; }
        data d1 = rmq1.query(l, r);
        data d2 = rmq2.query(l, r);
        if (d1.idx1 == d2.idx1) {
            cout << max(d1.v1 + d2.v2, d1.v2 + d2.v1) << "\n";
        } else {
            cout << d1.v1 + d2.v1 << "\n";
        }
    }
    return 0;
}


#include<bits/stdc++.h>

#define ll long long
#define INF 2147483647
#define lc(a) ((a) << 1)
#define rc(a) ((a) << 1 | 1)

int inp(){
    char c = getchar();
    while(c < '0' || c > '9')
        c = getchar();
    int sum = 0;
    while(c >= '0' && c <= '9'){
        sum = sum * 10 + c - '0';
        c = getchar();
    }
    return sum;
}

ll h[200010];
ll d[200010];

struct SEG{
    int l;
    int r;
    ll dis;
    ll sum;
    ll ls;
    ll rs;
};

SEG operator + (SEG a, SEG b){
    if(a.l == -1)
        return b;
    if(b.l == -1)
        return a;
    SEG ret;
    ret.l = a.l;
    ret.r = b.r;
    ret.sum = std::max(std::max(a.sum, b.sum), a.rs + b.ls);
    ret.ls = std::max(a.ls, a.dis + b.ls);
    ret.rs = std::max(b.rs, b.dis + a.rs);
    ret.dis = a.dis + b.dis;
    return ret;
}

struct SEG_Tree{
    SEG t[800000];

    void push_up(int cur){
        t[cur] = t[lc(cur)] + t[rc(cur)];
    }

    void build(int cur, int l, int r){
        t[cur].l = l;
        t[cur].r = r;
        if(l == r){
            t[cur].sum = 0;
            t[cur].ls = h[l];
            t[cur].rs = h[l] + d[l];
            t[cur].dis = d[l];
            return ;
        }
        int mid = (l + r) >> 1;
        build(lc(cur), l, mid);
        build(rc(cur), mid + 1, r);
        push_up(cur);
    }

    SEG query(int cur, int l, int r){
        if(t[cur].l > r || t[cur].r < l)
            return (SEG){-1, -1, -1, -1, -1, -1};
        if(t[cur].l >= l && t[cur].r <= r)
            return t[cur];
        return query(lc(cur), l, r) + query(rc(cur), l, r);
    }
}t;

int main(){
    int n = inp();
    int m = inp();
    for(int i = 1; i <= n; i++)
        d[i] = inp();
    for(int i = 1; i <= n; i++)
        h[i] = inp() << 1;
    for(int i = n + 1; i <= (n << 1); i++){
        d[i] = d[i - n];
        h[i] = h[i - n];
    }
    t.build(1, 1, (n << 1));
    while(m--){
        int l = inp();
        int r = inp();
        if(l > r){
            std::swap(l, r);
            l++;
            r--;
        } else {
            l += n;
            std::swap(l, r);
            l++;
            r--;
        }
        printf("%lld\n", t.query(1, l, r).sum);
    }
}


#include<bits/stdc++.h>

#define ll long long
#define INF 2147483647
#define lc(a) ((a) << 1)
#define rc(a) ((a) << 1 | 1)

int inp(){
    char c = getchar();
    while(c < '0' || c > '9')
        c = getchar();
    int sum = 0;
    while(c >= '0' && c <= '9'){
        sum = sum * 10 + c - '0';
        c = getchar();
    }
    return sum;
}

int h[200010];
int d[200010];

struct SEG{
    int l;
    int r;
    ll dis;
    ll sum;
    ll ls;
    ll rs;
};

SEG operator + (SEG a, SEG b){
    if(a.l == -1)
        return b;
    if(b.l == -1)
        return a;
    SEG ret;
    ret.l = a.l;
    ret.r = b.r;
    ret.sum = std::max(std::max(a.sum, b.sum), a.rs + b.ls);
    ret.ls = std::max(a.ls, a.dis + b.ls);
    ret.rs = std::max(b.rs, b.dis + a.rs - d[ret.r]);
    ret.dis = a.dis + b.dis;
    return ret;
}

struct SEG_Tree{
    SEG t[800000];

    void push_up(int cur){
        t[cur] = t[lc(cur)] + t[rc(cur)];
    }

    void build(int cur, int l, int r){
        t[cur].l = l;
        t[cur].r = r;
        if(l == r){
            t[cur].sum = 0;
            t[cur].ls = h[l];
            t[cur].rs = h[l] + d[l];
            t[cur].dis = d[l];
            return ;
        }
        int mid = (l + r) >> 1;
        build(lc(cur), l, mid);
        build(rc(cur), mid + 1, r);
        push_up(cur);
    }

    SEG query(int cur, int l, int r){
        if(t[cur].l > r || t[cur].r < l)
            return (SEG){-1, -1, -1, -1, -1, -1};
        if(t[cur].l >= l && t[cur].r <= r)
            return t[cur];
        return query(lc(cur), l, r) + query(rc(cur), l, r);
    }
}t;

int main(){
    int n = inp();
    int m = inp();
    for(int i = 1; i <= n; i++)
        d[i] = inp();
    for(int i = 1; i <= n; i++)
        h[i] = inp() << 1;
    for(int i = n + 1; i <= (n << 1); i++){
        d[i] = d[i - n];
        h[i] = h[i - n];
    }
    t.build(1, 1, (n << 1));
    while(m--){
        int l = inp();
        int r = inp();
        if(l > r){
            std::swap(l, r);
            l++;
            r--;
        } else {
            l += n;
            std::swap(l, r);
            l++;
            r--;
        }
        printf("%lld\n", t.query(1, l, r).sum);
    }
}


#include<bits/stdc++.h>

#define ll long long
#define INF 2147483647
#define lc(a) ((a) << 1)
#define rc(a) ((a) << 1 | 1)

int inp(){
    char c = getchar();
    while(c < '0' || c > '9')
        c = getchar();
    int sum = 0;
    while(c >= '0' && c <= '9'){
        sum = sum * 10 + c - '0';
        c = getchar();
    }
    return sum;
}

ll h[200010];
ll d[200010];

struct SEG{
    int l;
    int r;
    ll dis;
    ll sum;
    ll ls;
    ll rs;
};

SEG operator + (SEG a, SEG b){
    if(a.l == -1)
        return b;
    if(b.l == -1)
        return a;
    SEG ret;
    ret.l = a.l;
    ret.r = b.r;
    ret.sum = std::max(std::max(a.sum, b.sum), a.rs + b.ls);
    ret.ls = std::max(a.ls, a.dis + b.ls);
    ret.rs = std::max(b.rs, b.dis + a.rs);
    ret.dis = a.dis + b.dis;
    return ret;
}

struct SEG_Tree{
    SEG t[800000];

    void push_up(int cur){
        t[cur] = t[lc(cur)] + t[rc(cur)];
    }

    void build(int cur, int l, int r){
        t[cur].l = l;
        t[cur].r = r;
        if(l == r){
            t[cur].sum = 0;
            t[cur].ls = h[l];
            t[cur].rs = h[l] + d[l];
            t[cur].dis = d[l];
            return ;
        }
        int mid = (l + r) >> 1;
        build(lc(cur), l, mid);
        build(rc(cur), mid + 1, r);
        push_up(cur);
    }

    SEG query(int cur, int l, int r){
        if(t[cur].l > r || t[cur].r < l)
            return (SEG){-1, -1, -1, -1, -1, -1};
        if(t[cur].l >= l && t[cur].r <= r)
            return t[cur];
        return query(lc(cur), l, r) + query(rc(cur), l, r);
    }
}t;

int main(){
    int n = inp();
    int m = inp();
    for(int i = 1; i <= n; i++)
        d[i] = inp();
    for(int i = 1; i <= n; i++)
        h[i] = inp() << 1;
    for(int i = n + 1; i <= (n << 1); i++){
        d[i] = d[i - n];
        h[i] = h[i - n];
    }
    t.build(1, 1, (n << 1));
    while(m--){
        int l = inp();
        int r = inp();
        if(l > r){
            std::swap(l, r);
            l++;
            r--;
        } else {
            l += n;
            std::swap(l, r);
            l++;
            r--;
        }
        printf("%lld\n", t.query(1, l, r).sum);
    }
}
// ...


#include<bits/stdc++.h>

#define ll long long
#define INF 2147483647
#define lc(a) ((a) << 1)
#define rc(a) ((a) << 1 | 1)

int inp(){
    char c = getchar();
    while(c < '0' || c > '9')
        c = getchar();
    int sum = 0;
    while(c >= '0' && c <= '9'){
        sum = sum * 10 + c - '0';
        c = getchar();
    }
    return sum;
}

int h[200010];
int d[200010];

struct SEG{
    int l;
    int r;
    ll dis;
    ll sum;
    ll ls;
    ll rs;
};

SEG operator + (SEG a, SEG b){
    if(a.l == -1)
        return b;
    if(b.l == -1)
        return a;
    SEG ret;
    ret.l = a.l;
    ret.r = b.r;
    ret.sum = std::max(std::max(a.sum, b.sum), a.rs + b.ls);
    ret.ls = std::max(a.ls, a.dis + b.ls);
    ret.rs = std::max(b.rs, b.dis + a.rs);
    ret.dis = a.dis + b.dis;
    return ret;
}

struct SEG_Tree{
    SEG t[800000];

    void push_up(int cur){
        t[cur] = t[lc(cur)] + t[rc(cur)];
    }

    void build(int cur, int l, int r){
        t[cur].l = l;
        t[cur].r = r;
        if(l == r){
            t[cur].sum = 0;
            t[cur].ls = h[l];
            t[cur].rs = h[l] + d[l];
            t[cur].dis = d[l];
            return ;
        }
        int mid = (l + r) >> 1;
        build(lc(cur), l, mid);
        build(rc(cur), mid + 1, r);
        push_up(cur);
    }

    SEG query(int cur, int l, int r){
        if(t[cur].l > r || t[cur].r < l)
            return (SEG){-1, -1, -1, -1, -1, -1};
        if(t[cur].l >= l && t[cur].r <= r)
            return t[cur];
        return query(lc(cur), l, r) + query(rc(cur), l, r);
    }
}t;

int main(){
    int n = inp();
    int m = inp();
    for(int i = 1; i <= n; i++)
        d[i] = inp();
    for(int i = 1; i <= n; i++)
        h[i] = inp() << 1;
    for(int i = n + 1; i <= (n << 1); i++){
        d[i] = d[i - n];
        h[i] = h[i - n];
    }
    t.build(1, 1, (n << 1));
    while(m--){
        int l = inp();
        int r = inp();
        if(l > r){
            std::swap(l, r);
            l++;
            r--;
        } else {
            l += n;
            std::swap(l, r);
            l++;
            r--;
        }
        printf("%lld\n", t.query(1, l, r).sum);
    }
}


#include <bits/stdc++.h>
#define fastIO ios::sync_with_stdio(NULL); cin.tie(NULL);

using namespace std;
const int N = 1E6+7;
const long long INF = 1E18;

struct data
{
    long long sum_1, sum_2, comb;
} NODE[N];
int n,q;
long long pre[N], d[N], h[N];

void build_tree(int id,int s,int e)
{
    if (s > e) return;

    if (s == e)
    {
        NODE[id].sum_1 = 2*h[s]+pre[s-1];
        NODE[id].sum_2 = 2*h[s]-pre[s-1];
        NODE[id].comb = -INF;
        return;
    }

    int mid = (s+e)>>1;

    build_tree(id*2,s,mid);
    build_tree(id*2+1,mid+1,e);
    NODE[id].sum_1 = max(NODE[id*2].sum_1,NODE[id*2+1].sum_1);
    NODE[id].sum_2 = max(NODE[id*2].sum_2,NODE[id*2+1].sum_2);
    long long tmp_3 = NODE[id*2].sum_2 + NODE[id*2+1].sum_1;
    NODE[id].comb = max(NODE[id*2].comb,max(NODE[id*2+1].comb, tmp_3));
}

data get_max_sum(int id,int s,int e,int l,int r)
{
    data ans;
    if (s > e || s > r || e < l) return {-INF,-INF,-INF};

    if (l <= s && e <= r) return NODE[id];

    int mid = (s+e)>>1;
    data tmp_1 = get_max_sum(id*2,s,mid,l,r);
    data tmp_2 = get_max_sum(id*2+1,mid+1,e,l,r);

    ans.sum_1 = max(tmp_1.sum_1,tmp_2.sum_1);
    ans.sum_2 = max(tmp_1.sum_2,tmp_2.sum_2);
    long long t_3 = tmp_1.sum_2 + tmp_2.sum_1;
    ans.comb = max(tmp_1.comb, max(tmp_2.comb, t_3));

return ans;
}

int main()
{
    fastIO
    cin>>n>>q;

    for (int i = 1;i <= n;++i)
    {
        cin>>d[i];
        d[i+n] = d[i];
    }

    for (int i = 1;i <= n;++i)
    {
        cin>>h[i];
        h[i+n] = h[i];
    }

    n = n * 2;

    for (int i = 1;i <= n;++i) pre[i] = pre[i-1] + d[i];

    build_tree(1,1,n);

    while (q--)
    {
        int l,r;
        cin>>l>>r;

        if (l > r) r = r + (n/2);
        cout<<get_max_sum(1,1,n,r+1,l+(n/2)-1).comb<<"\n";
    }

}


//besmellah
#include <bits/stdc++.h>
using namespace std;

#define int long long

struct Node {
	int D = 0, D2 = 0, seg = 0, pref = 0, suff = 0;
};

const int maxn = 1e5 + 5;
int d[maxn], h[maxn], n;
Node seg[4 * maxn];

void build(int id, int L, int R) {
	if (R == L + 1) {
		seg[id].D = d[L];
		seg[id].D2 = d[(L - 1 + n) % n] + seg[id].D;
		seg[id].pref = seg[id].suff = 2 * h[L];
//		seg[id].pref += d[(L - 1 + n) % n];
		seg[id].suff += d[L];
		return;
	}
	int mid = (L + R) / 2;
	build(2 * id + 0, L, mid);
	build(2 * id + 1, mid, R);
	seg[id].D = seg[2 * id].D + seg[2 * id + 1].D;
	seg[id].D2 = seg[2 * id].D2 + seg[2 * id + 1].D;
	seg[id].pref = max(seg[2 * id].pref, seg[2 * id + 1].pref + seg[2 * id].D);
	seg[id].suff = max(seg[2 * id + 1].suff, seg[2 * id].suff + seg[2 * id + 1].D);
	seg[id].seg = max(max(seg[2 * id].seg, seg[2 * id + 1].seg), seg[2 * id].suff + seg[2 * id + 1].pref);
//	cout << L << ' ' << R << " D " << seg[id].D << " D2 " << seg[id].D2 << " pref " << seg[id].pref << " suff " << seg[id].suff << " seg " << seg[id].seg << endl;
}

Node get(int id, int L, int R, int l, int r) {
	Node ans;
	if (R <= l || r <= L || r <= l)
		return ans;
	if (L >= l && R <= r)
		return seg[id];
	int mid = (L + R) / 2;
	Node P = get(2 * id, L, mid, l, r), Q = get(2 * id + 1, mid, R, l, r);
	ans.D = P.D + Q.D;
	ans.D2 = P.D2 + Q.D;
	ans.pref = max(P.pref, Q.pref + P.D);
	ans.suff = max(Q.suff, P.suff + Q.D);
	ans.seg = max(max(P.seg, Q.seg), P.suff + Q.pref);
	return ans;
}

int32_t main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	int m;
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		cin >> d[i];
	}
	for (int i = 0; i < n; i++) {
		cin >> h[i];
	}
	build(1, 0, n);
	for (int i = 0; i < m; i++) {
		int a, b;
		cin >> a >> b;
		a--;
		b--;
		if (a <= b) {
			Node P = get(1, 0, n, 0, a);
			Node Q = get(1, 0, n, b + 1, n);
			cout << max(max(P.seg, Q.seg), Q.suff + P.pref) << '\n';
		}
		else {
			cout << get(1, 0, n, b + 1, a).seg << '\n';
		}
	}
}


//besmellah
#include <bits/stdc++.h>
using namespace std;

#define int long long

struct Node {
	int D = -1e9, D2 = -1e9, seg = -1e9, pref = -1e9, suff = -1e9;
};

const int maxn = 1e5 + 5;
int d[maxn], h[maxn], n;
Node seg[4 * maxn];

void build(int id, int L, int R) {
	if (R == L + 1) {
		seg[id].D = d[L];
		seg[id].D2 = d[(L - 1 + n) % n] + seg[id].D;
		seg[id].pref = seg[id].suff = 2 * h[L];
//		seg[id].pref += d[(L - 1 + n) % n];
		seg[id].suff += d[L];
		return;
	}
	int mid = (L + R) / 2;
	build(2 * id + 0, L, mid);
	build(2 * id + 1, mid, R);
	seg[id].D = seg[2 * id].D + seg[2 * id + 1].D;
	seg[id].D2 = seg[2 * id].D2 + seg[2 * id + 1].D;
	seg[id].pref = max(seg[2 * id].pref, seg[2 * id + 1].pref + seg[2 * id].D);
	seg[id].suff = max(seg[2 * id + 1].suff, seg[2 * id].suff + seg[2 * id + 1].D);
	seg[id].seg = max(max(seg[2 * id].seg, seg[2 * id + 1].seg), seg[2 * id].suff + seg[2 * id + 1].pref);
//	cout << L << ' ' << R << " D " << seg[id].D << " D2 " << seg[id].D2 << " pref " << seg[id].pref << " suff " << seg[id].suff << " seg " << seg[id].seg << endl;
}

Node get(int id, int L, int R, int l, int r) {
	Node ans;
	if (R <= l || r <= L || r <= l)
		return ans;
	if (L >= l && R <= r)
		return seg[id];
	int mid = (L + R) / 2;
	Node P = get(2 * id, L, mid, l, r), Q = get(2 * id + 1, mid, R, l, r);
	ans.D = P.D + Q.D;
	ans.D2 = P.D2 + Q.D;
	ans.pref = max(P.pref, Q.pref + P.D);
	ans.suff = max(Q.suff, P.suff + Q.D);
	ans.seg = max(max(P.seg, Q.seg), P.suff + Q.pref);
	return ans;
}

int32_t main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	int m;
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		cin >> d[i];
	}
	for (int i = 0; i < n; i++) {
		cin >> h[i];
	}
	build(1, 0, n);
	for (int i = 0; i < m; i++) {
		int a, b;
		cin >> a >> b;
		a--;
		b--;
		if (a <= b) {
			Node P = get(1, 0, n, 0, a);
			Node Q = get(1, 0, n, b + 1, n);
			cout << max(max(P.seg, Q.seg), Q.suff + P.pref) << '\n';
		}
		else {
			cout << get(1, 0, n, b + 1, a).seg << '\n';
		}
	}
}


//besmellah
#include <bits/stdc++.h>
using namespace std;

#define int long long

struct Node {
	int D = 0, D2 = 0, seg = 0, pref = 0, suff = 0;
};

const int maxn = 1e5 + 5;
int d[maxn], h[maxn], n;
Node seg[4 * maxn];

void build(int id, int L, int R) {
	if (R == L + 1) {
		seg[id].D = d[L];
		seg[id].D2 = d[(L - 1 + n) % n] + seg[id].D;
		seg[id].pref = seg[id].suff = 2 * h[L];
		seg[id].pref += d[(L - 1 + n) % n];
		return;
	}
	int mid = (L + R) / 2;
	build(2 * id + 0, L, mid);
	build(2 * id + 1, mid, R);
	seg[id].D = seg[2 * id].D + seg[2 * id + 1].D;
	seg[id].D2 = seg[2 * id].D2 + seg[2 * id + 1].D;
	seg[id].pref = max(seg[2 * id].pref, seg[2 * id + 1].pref + seg[2 * id].D);
	seg[id].suff = max(seg[2 * id + 1].suff, seg[2 * id].suff + seg[2 * id + 1].D);
	seg[id].seg = max(max(seg[2 * id].seg, seg[2 * id + 1].seg), seg[2 * id].suff + seg[2 * id + 1].pref);
//	cout << L << ' ' << R << " D " << seg[id].D << " D2 " << seg[id].D2 << " pref " << seg[id].pref << " suff " << seg[id].suff << " seg " << seg[id].seg << endl;
}

Node get(int id, int L, int R, int l, int r) {
	Node ans;
	if (R <= l || r <= L || r <= l)
		return ans;
	if (L >= l && R <= r)
		return seg[id];
	int mid = (L + R) / 2;
	Node P = get(2 * id, L, mid, l, r), Q = get(2 * id + 1, mid, R, l, r);
	ans.D = P.D + Q.D;
	ans.D2 = P.D2 + Q.D;
	ans.pref = max(P.pref, Q.pref + P.D);
	ans.suff = max(Q.suff, P.suff + Q.D);
	ans.seg = max(max(P.seg, Q.seg), P.suff + Q.pref);
	return ans;
}

int32_t main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	int m;
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		cin >> d[i];
	}
	for (int i = 0; i < n; i++) {
		cin >> h[i];
	}
	build(1, 0, n);
	for (int i = 0; i < m; i++) {
		int a, b;
		cin >> a >> b;
		a--;
		b--;
		if (a <= b) {
			Node P = get(1, 0, n, 0, a);
			Node Q = get(1, 0, n, b + 1, n);
			cout << max(max(P.seg, Q.seg), Q.suff + P.pref) << '\n';
		}
		else {
			cout << get(1, 0, n, b + 1, a).seg << '\n';
		}
	}
}


#include<bits/stdc++.h>
#define ts cout<<"ok"<<endl
#define int long long
#define hh puts("")
#define pc putchar
#define ls(x) ((x)<<1)
#define rs(x) ((x)<<1|1)
//#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
//char buf[1<<21],*p1=buf,*p2=buf;
using namespace std;
const int N=200005;
int n,m,d[N],h[N],sum[N],mx1[N<<2],mx2[N<<2],mx[N<<2];
struct node{
	int mx1,mx2,mx;
};
inline int read(){
    int ret=0,ff=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-') ff=-1;ch=getchar();}
    while(isdigit(ch)){ret=ret*10+(ch^48);ch=getchar();}
    return ret*ff;
}
void write(int x){if(x<0){x=-x,pc('-');}if(x>9) write(x/10);pc(x%10+48);}
void writeln(int x){write(x),hh;}
void writesp(int x){write(x),pc(' ');}
void build(int l,int r,int k){
	if(l==r){
		mx1[k]=2*h[l]+sum[l];
		mx2[k]=2*h[l]-sum[l];
		mx[k]=-1e18;
		return;
	}
	int mid=(l+r)>>1;
	build(l,mid,ls(k));
	build(mid+1,r,rs(k));
	mx1[k]=max(mx1[ls(k)],mx1[rs(k)]);
	mx2[k]=max(mx2[ls(k)],mx2[rs(k)]);
	mx[k]=max(mx2[ls(k)]+mx1[rs(k)],max(mx[ls(k)],mx[rs(k)]));
}
node query(int l,int r,int x,int y,int k){
	if(x<=l&&r<=y) return (node){mx1[k],mx2[k],mx[k]};
	int mid=(l+r)>>1;
	if(y<=mid){
		return query(l,mid,x,y,ls(k));
	}
	else if(x>=mid+1){
		return query(mid+1,r,x,y,rs(k));
	}
	else{
		node L=query(l,mid,x,mid,ls(k)),R=query(mid+1,r,mid+1,y,rs(k));
		return (node){max(L.mx1,R.mx1),max(L.mx2,R.mx2),max(R.mx1+L.mx2,max(L.mx,R.mx))};
	}
}
signed main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++) d[i]=d[i+n]=read();
	for(int i=1;i<=n;i++) h[i]=h[i+n]=read();
	for(int i=2;i<=2*n;i++) sum[i]=sum[i-1]+d[i-1];
	build(1,2*n,1);
	while(m--){
		int x=read(),y=read();
		if(x<=y) writeln(query(1,2*n,y+1,x+n-1,1).mx);
		else writeln(query(1,2*n,y+1,x-1,1).mx);
	}
    return 0;
}


#include<bits/stdc++.h>
#define ts cout<<"ok"<<endl
#define int long long
#define hh puts("")
#define pc putchar
#define ls(x) ((x)<<1)
#define rs(x) ((x)<<1|1)
//#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
//char buf[1<<21],*p1=buf,*p2=buf;
using namespace std;
const int N=200005;
int n,m,d[N],h[N],sum[N],mx1[N<<2],mx2[N<<2],mx[N];
struct node{
	int mx1,mx2,mx;
};
inline int read(){
    int ret=0,ff=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-') ff=-1;ch=getchar();}
    while(isdigit(ch)){ret=ret*10+(ch^48);ch=getchar();}
    return ret*ff;
}
void write(int x){if(x<0){x=-x,pc('-');}if(x>9) write(x/10);pc(x%10+48);}
void writeln(int x){write(x),hh;}
void writesp(int x){write(x),pc(' ');}
void build(int l,int r,int k){
	if(l==r){
		mx1[k]=2*h[l]+sum[l];
		mx2[k]=2*h[l]-sum[l];
		mx[k]=-1e18;
		return;
	}
	int mid=(l+r)>>1;
	build(l,mid,ls(k));
	build(mid+1,r,rs(k));
	mx1[k]=max(mx1[ls(k)],mx1[rs(k)]);
	mx2[k]=max(mx2[ls(k)],mx2[rs(k)]);
	mx[k]=max(mx2[ls(k)]+mx1[rs(k)],max(mx[ls(k)],mx[rs(k)]));
}
node query(int l,int r,int x,int y,int k){
	if(x<=l&&r<=y) return (node){mx1[k],mx2[k],mx[k]};
	int mid=(l+r)>>1;
	if(y<=mid){
		return query(l,mid,x,y,ls(k));
	}
	else if(x>=mid+1){
		return query(mid+1,r,x,y,rs(k));
	}
	else{
		node L=query(l,mid,x,mid,ls(k)),R=query(mid+1,r,mid+1,y,rs(k));
		return (node){max(L.mx1,R.mx1),max(L.mx2,R.mx2),max(R.mx1+L.mx2,max(L.mx,R.mx))};
	}
}
signed main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++) d[i]=d[i+n]=read();
	for(int i=1;i<=n;i++) h[i]=h[i+n]=read();
	for(int i=2;i<=2*n;i++) sum[i]=sum[i-1]+d[i-1];
	build(1,2*n,1);
	while(m--){
		int x=read(),y=read();
		if(x<=y) writeln(query(1,2*n,y+1,x+n-1,1).mx);
		else writeln(query(1,2*n,y+1,x-1,1).mx);
	}
    return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ls (x<<1)
#define rs (x<<1|1)
#define N 400005
#define mid ((l+r)>>1)
using namespace std;
const int inf=1000000007;
struct zero{
  int a,b,baka;
}tree[N<<2];
//2*h[i]-sum[i]
//2*h[i]+sum[i]
// ans
int h[N],sum[N],n,m;
int d[N];
void push_up(int x){
  int a=tree[ls].baka,b=tree[rs].baka,c=tree[rs].b+tree[ls].a;
  if(c>a&&c>b)tree[x]=(zero){tree[ls].a,tree[rs].b,c};
  else if(b>a)tree[x]=tree[rs];
  else tree[x]=tree[ls];
}
void build(int x,int l,int r){
  if(l==r){
    tree[x].a=2*h[l]-sum[l];
    tree[x].b=2*h[l]+sum[l];
    tree[x].baka=-inf;
    // cout<<"fixed:"<<x<<" "<<l<<" "<<r<<" "<<tree[x].a<<" "<<tree[x].b<<endl;
    return;
  }
  build(ls,l,mid);
  build(rs,mid+1,r);
  push_up(x);
  // cout<<"error:"<<x<<" "<<l<<" "<<r<<" "<<tree[x].a<<" "<<tree[x].b<<" "<<tree[x].baka<<endl;
}
zero query(int x,int l,int r,int L,int R){
  // cout<<"query:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<"\n";
  int ans=0;
  zero plk1,plk2;
  plk1.a=plk2.b=plk1.baka=plk2.baka=-2*inf;
  bool op1=false,op2=false;
  if(L<=l&&r<=R){/*cout<<"GG"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<tree[x].a<<" "<<tree[x].b<<" "<<tree[x].baka<<endl;*/return tree[x];}
  if(mid>=L)plk1=query(ls,l,mid,L,R),op1=1;
  if(mid<R)plk2=query(rs,mid+1,r,L,R),op2=1;
  // cout<<ls<<" "<<l<<" "<<mid<<" "<<L<<" "
  if(op1&&plk1.baka>plk2.baka&&plk1.baka>(plk2.b+plk1.a)){ /* cout<<"query:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<plk1.baka<<endl; */return plk1;}
  else if(op2&&plk2.baka>(plk2.b+plk1.a)){/*  cout<<"query:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<plk2.baka<<endl; */return plk2;}
  else {  return(zero){plk1.a,plk2.b,plk1.a+plk2.b};}
}
int main(){
  scanf("%d%d",&n,&m);
  for(int i=1;i<=n;i++)scanf("%d",d+i);
  for(int i=2;i<=n+1;i++)sum[i]=sum[i-1]+d[i-1];
  for(int i=n+2;i<=n*2;i++)sum[i]=sum[i-1]+d[i-n-1];
  for(int i=1;i<=n;i++)scanf("%d",h+i);
  for(int i=n+1;i<=2*n;i++)h[i]=h[i-n];
  build(1,1,2*n);
  for(int i=1;i<=m;i++){
    int a,b;
    scanf("%d%d",&a,&b);
    if(a<=b)printf("%d\n",query(1,1,2*n,b+1,a+n-1).baka);
    else printf("%d\n",query(1,1,2*n,b+1,a-1).baka);
  }
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ls (x<<1)
#define rs (x<<1|1)
#define N 400005
#define mid ((l+r)>>1)
using namespace std;
const int inf=1000000007;
struct zero{
  int a,b,baka;
}tree[N<<2];
//2*h[i]-sum[i]
//2*h[i]+sum[i]
// ans
int h[N],sum[N],n,m;
int d[N];
void push_up(int x){
  int a=tree[ls].baka,b=tree[rs].baka,c=tree[rs].b+tree[ls].a;
  if(c>a&&c>b)tree[x]=(zero){tree[ls].a,tree[rs].b,c};
  else if(b>a)tree[x]=tree[rs];
  else tree[x]=tree[ls];
}
void build(int x,int l,int r){
  if(l==r){
    tree[x].a=2*h[l]-sum[l];
    tree[x].b=2*h[l]+sum[l];
    tree[x].baka=-inf;
    // cout<<"fixed:"<<x<<" "<<l<<" "<<r<<" "<<tree[x].a<<" "<<tree[x].b<<endl;
    return;
  }
  build(ls,l,mid);
  build(rs,mid+1,r);
  push_up(x);
  // cout<<"error:"<<x<<" "<<l<<" "<<r<<" "<<tree[x].a<<" "<<tree[x].b<<" "<<tree[x].baka<<endl;
}
zero query(int x,int l,int r,int L,int R){
  // cout<<"query:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" ";
  int ans=0;
  zero plk1,plk2;
  plk1.a=plk2.b=plk1.baka=plk2.baka=-2*inf;
  bool op1=false,op2=false;
  if(L<=l&&r<=R){return tree[x];}
  if(mid>=L)plk1=query(ls,l,mid,L,R),op1=1;
  if(mid<R)plk2=query(rs,mid+1,r,L,R),op2=1;
  // cout<<ls<<" "<<l<<" "<<mid<<" "<<L<<" "
  if(op1&&plk1.baka>plk2.baka&&plk1.baka>(plk2.b+plk1.a)){ return plk1;}
  else if(op2&&plk2.baka>(plk2.b+plk1.a)){ return plk2;}
  else {  return(zero){plk1.a,plk2.b,plk1.a+plk2.b};}
}
int main(){
  scanf("%d%d",&n,&m);
  for(int i=1;i<=n;i++)scanf("%d",d+i);
  for(int i=2;i<=n+1;i++)sum[i]=sum[i-1]+d[i-1];
  for(int i=n+2;i<=n*2;i++)sum[i]=sum[i-1]+d[i-n-1];
  for(int i=1;i<=n;i++)scanf("%d",h+i);
  for(int i=n+1;i<=2*n;i++)h[i]=h[i-n];
  build(1,1,2*n);
  for(int i=1;i<=m;i++){
    int a,b;
    scanf("%d%d",&a,&b);
    if(a<=b)printf("%d\n",query(1,1,2*n,b+1,a+n-1).baka);
    else printf("%d\n",query(1,1,2*n,a+1,b-1).baka);
  }
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ls (x<<1)
#define rs (x<<1|1)
#define N 400005
#define mid ((l+r)>>1)
using namespace std;
const int inf=1000000007;
struct zero{
  int a,b,baka;
}tree[N<<2];
//2*h[i]-sum[i]
//2*h[i]+sum[i]
// ans
int h[N],sum[N],n,m;
int d[N];
void push_up(int x){
  int a=tree[ls].baka,b=tree[rs].baka,c=tree[rs].b+tree[ls].a;
  if(c>a&&c>b)tree[x]=(zero){tree[ls].a,tree[rs].b,c};
  else if(b>a)tree[x]=tree[rs];
  else tree[x]=tree[ls];
}
void build(int x,int l,int r){
  if(l==r){
    tree[x].a=2*h[l]-sum[l];
    tree[x].b=2*h[l]+sum[l];
    tree[x].baka=-inf;
    // cout<<"fixed:"<<x<<" "<<l<<" "<<r<<" "<<tree[x].a<<" "<<tree[x].b<<endl;
    return;
  }
  build(ls,l,mid);
  build(rs,mid+1,r);
  push_up(x);
  // cout<<"error:"<<x<<" "<<l<<" "<<r<<" "<<tree[x].a<<" "<<tree[x].b<<" "<<tree[x].baka<<endl;
}
zero query(int x,int l,int r,int L,int R){
  // cout<<"query:"<<x<<" "<<l<<" "<<r<.<" "<<L<<" "<<R<<"\n";
  int ans=0;
  zero plk1,plk2;
  plk1.a=plk2.b=plk1.baka=plk2.baka=-2*inf;
  bool op1=false,op2=false;
  if(L<=l&&r<=R){/*cout<<"GG"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<tree[x].a<<" "<<tree[x].b<<" "<<tree[x].baka<<endl;*/return tree[x];}
  if(mid>=L)plk1=query(ls,l,mid,L,R),op1=1;
  if(mid<R)plk2=query(rs,mid+1,r,L,R),op2=1;
  // cout<<ls<<" "<<l<<" "<<mid<<" "<<L<<" "
  if(op1&&plk1.baka>plk2.baka&&plk1.baka>(plk2.b+plk1.a)){ /* cout<<"query:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<plk1.baka<<endl; */return plk1;}
  else if(op2&&plk2.baka>(plk2.b+plk1.a)){/*  cout<<"query:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<plk2.baka<<endl; */return plk2;}
  else {  return(zero){plk1.a,plk2.b,plk1.a+plk2.b};}
}
int main(){
  scanf("%d%d",&n,&m);
  for(int i=1;i<=n;i++)scanf("%d",d+i);
  for(int i=2;i<=n+1;i++)sum[i]=sum[i-1]+d[i-1];
  for(int i=n+2;i<=n*2;i++)sum[i]=sum[i-1]+d[i-n-1];
  for(int i=1;i<=n;i++)scanf("%d",h+i);
  for(int i=n+1;i<=2*n;i++)h[i]=h[i-n];
  build(1,1,2*n);
  for(int i=1;i<=m;i++){
    int a,b;
    scanf("%d%d",&a,&b);
    if(a<=b)printf("%d\n",query(1,1,2*n,b+1,a+n-1).baka);
    else printf("%d\n",query(1,1,2*n,a+1,(b+n-2)%n+1).baka);
  }
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ls (x<<1)
#define rs (x<<1|1)
#define N 400005
#define mid ((l+r)>>1)
using namespace std;
const int inf=1000000007;
struct zero{
  int a,b,baka;
}tree[N<<2];
//2*h[i]-sum[i]
//2*h[i]+sum[i]
// ans
int h[N],sum[N],n,m;
int d[N];
void push_up(int x){
  tree[x]=(zero){max(tree[ls].a,tree[rs].a),max(tree[ls].b,tree[rs].b),max(tree[ls].baka,max(tree[rs].baka,tree[ls].a+tree[rs].b))};
}
void build(int x,int l,int r){
  if(l==r){
    tree[x].a=2*h[l]-sum[l];
    tree[x].b=2*h[l]+sum[l];
    tree[x].baka=-inf;
    // cout<<"fixed:"<<x<<" "<<l<<" "<<r<<" "<<tree[x].a<<" "<<tree[x].b<<endl;
    return;
  }
  build(ls,l,mid);
  build(rs,mid+1,r);
  push_up(x);
  // cout<<"error:"<<x<<" "<<l<<" "<<r<<" "<<tree[x].a<<" "<<tree[x].b<<" "<<tree[x].baka<<endl;
}
zero query(int x,int l,int r,int L,int R){
  // cout<<"query:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<"\n";
  int ans=0;
  zero plk1,plk2;
  plk1.a=plk2.b=plk1.baka=plk2.baka=-2*inf;
  if(L<=l&&r<=R){/* cout<<"GG:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<tree[x].a<<" "<<tree[x].b<<" "<<tree[x].baka<<endl; */return tree[x];}
  if(mid>=L)plk1=query(ls,l,mid,L,R);
  if(mid<R)plk2=query(rs,mid+1,r,L,R);
  // cout<<ls<<" "<<l<<" "<<mid<<" "<<L<<" "
  int a=plk1.baka,b=plk2.baka,c=plk2.b+plk1.a;
  if(a>b&&a>c){ /* cout<<"query1:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<plk1.a<<" "<<plk1.b<<" "<<a<<endl; */return plk1;}
  else if(b>c){ /* cout<<"query2:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<plk2.a<<" " <<plk2.b<<" "<<b<<endl; */return plk2;}
  else { /* cout<<"query3:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<plk1.a<<" "<<plk2.b<<" "<<c<<endl; */ return(zero){plk1.a,plk2.b,plk1.a+plk2.b};}
}
int main(){
  scanf("%d%d",&n,&m);
  for(int i=1;i<=n;i++)scanf("%d",d+i);
  for(int i=2;i<=n+1;i++)sum[i]=sum[i-1]+d[i-1];
  for(int i=n+2;i<=n*2;i++)sum[i]=sum[i-1]+d[i-n-1];
  for(int i=1;i<=n;i++)scanf("%d",h+i);
  for(int i=n+1;i<=2*n;i++)h[i]=h[i-n];
  build(1,1,2*n);
  for(int i=1;i<=m;i++){
    int a,b;
    scanf("%d%d",&a,&b);
    if(a<=b)printf("%d\n",query(1,1,2*n,b+1,a+n-1).baka);
    else printf("%d\n",query(1,1,2*n,b+1,a-1).baka);
  }
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ls (x<<1)
#define rs (x<<1|1)
#define N 4000005
#define mid ((l+r)>>1)
#define int long long
using namespace std;
const int inf=100000000000007;
struct zero{
  int a,b,c;
}tree[N<<2];
//2*h[i]-sum[i]
//2*h[i]+sum[i]
// ans
int h[N],sum[N],n,m;
int d[N];
void push_up(int x){
  tree[x]=(zero){max(tree[ls].a,tree[rs].a),max(tree[ls].b,tree[rs].b),max(tree[ls].c,max(tree[rs].c,tree[ls].a+tree[rs].b))};
}
void build(int x,int l,int r){
  if(l==r){
    tree[x].a=2*h[l]-sum[l];
    tree[x].b=2*h[l]+sum[l];
    tree[x].c=-inf;
    // cout<<"fixed:"<<x<<" "<<l<<" "<<r<<" "<<tree[x].a<<" "<<tree[x].b<<endl;
    return;
  }
  build(ls,l,mid);
  build(rs,mid+1,r);
  push_up(x);
  // cout<<"error:"<<x<<" "<<l<<" "<<r<<" "<<tree[x].a<<" "<<tree[x].b<<" "<<tree[x].c<<endl;
}
zero query(int x,int l,int r,int L,int R){
  // cout<<"query:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<"\n";
  int ans=0;
  zero plk1,plk2;
  plk1.a=plk2.b=plk1.c=plk2.c=-2*inf;
  if(L<=l&&r<=R){/* cout<<"GG:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<tree[x].a<<" "<<tree[x].b<<" "<<tree[x].c<<endl; */return tree[x];}
  if(mid>=L)plk1=query(ls,l,mid,L,R);
  if(mid<R)plk2=query(rs,mid+1,r,L,R);
  // cout<<ls<<" "<<l<<" "<<mid<<" "<<L<<" "
  return (zero){max(plk1.a,plk2.a),max(plk1.b,plk2.b),max(plk1.c,max(plk2.c,plk1.a+plk2.b))};

  // if(a>b&&a>c){ /* cout<<"query1:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<plk1.a<<" "<<plk1.b<<" "<<a<<endl; */return plk1;}
  // else if(b>c){ /* cout<<"query2:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<plk2.a<<" " <<plk2.b<<" "<<b<<endl; */return plk2;}
  // else { /* cout<<"query3:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<plk1.a<<" "<<plk2.b<<" "<<c<<endl; */ return(zero){plk1.a,plk2.b,plk1.a+plk2.b};}
}
signed main(){
  scanf("%lld%lld",&n,&m);
  for(int i=1;i<=n;i++)scanf("%lld",d+i);
  for(int i=1;i<=n+1;i++)sum[i]=sum[i-1]+d[i-1];
  for(int i=n+2;i<=n*2;i++)sum[i]=sum[i-1]+d[i-n-1];
  for(int i=1;i<=n;i++)scanf("%lld",h+i);
  for(int i=n+1;i<=2*n;i++)h[i]=h[i-n];
  build(1,1,2*n);
  for(int i=1;i<=m;i++){
    int a,b;
    scanf("%lld%lld",&a,&b);
    if(a<=b)printf("%lld\n",query(1,1,2*n,b+1,a+n-1).c);
    else printf("%lld\n",query(1,1,2*n,b+1,a-1).c);
  }
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ls (x<<1)
#define rs (x<<1|1)
#define N 4000005
#define mid ((l+r)>>1)
#define int long long
using namespace std;
const int inf=100000000000007;
struct zero{
  int a,b,baka;
}tree[N<<2];
//2*h[i]-sum[i]
//2*h[i]+sum[i]
// ans
int h[N],sum[N],n,m;
int d[N];
void push_up(int x){
  tree[x]=(zero){max(tree[ls].a,tree[rs].a),max(tree[ls].b,tree[rs].b),max(tree[ls].baka,max(tree[rs].baka,tree[ls].a+tree[rs].b))};
}
void build(int x,int l,int r){
  if(l==r){
    tree[x].a=2*h[l]-sum[l];
    tree[x].b=2*h[l]+sum[l];
    tree[x].baka=-inf;
    // cout<<"fixed:"<<x<<" "<<l<<" "<<r<<" "<<tree[x].a<<" "<<tree[x].b<<endl;
    return;
  }
  build(ls,l,mid);
  build(rs,mid+1,r);
  push_up(x);
  // cout<<"error:"<<x<<" "<<l<<" "<<r<<" "<<tree[x].a<<" "<<tree[x].b<<" "<<tree[x].baka<<endl;
}
zero query(int x,int l,int r,int L,int R){
  // cout<<"query:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<"\n";
  int ans=0;
  zero plk1,plk2;
  plk1.a=plk2.b=plk1.baka=plk2.baka=-2*inf;
  if(L<=l&&r<=R){/* cout<<"GG:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<tree[x].a<<" "<<tree[x].b<<" "<<tree[x].baka<<endl; */return tree[x];}
  if(mid>=L)plk1=query(ls,l,mid,L,R);
  if(mid<R)plk2=query(rs,mid+1,r,L,R);
  // cout<<ls<<" "<<l<<" "<<mid<<" "<<L<<" "
  int a=plk1.baka,b=plk2.baka,c=plk2.b+plk1.a;
  if(a>b&&a>c){ /* cout<<"query1:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<plk1.a<<" "<<plk1.b<<" "<<a<<endl; */return plk1;}
  else if(b>c){ /* cout<<"query2:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<plk2.a<<" " <<plk2.b<<" "<<b<<endl; */return plk2;}
  else { /* cout<<"query3:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<plk1.a<<" "<<plk2.b<<" "<<c<<endl; */ return(zero){plk1.a,plk2.b,plk1.a+plk2.b};}
}
signed main(){
  scanf("%lld%lld",&n,&m);
  for(int i=1;i<=n;i++)scanf("%lld",d+i);
  for(int i=1;i<=n+1;i++)sum[i]=sum[i-1]+d[i-1];
  for(int i=n+2;i<=n*2;i++)sum[i]=sum[i-1]+d[i-n-1];
  for(int i=1;i<=n;i++)scanf("%lld",h+i);
  for(int i=n+1;i<=2*n;i++)h[i]=h[i-n];
  build(1,1,2*n);
  for(int i=1;i<=m;i++){
    int a,b;
    scanf("%lld%lld",&a,&b);
    if(a<=b)printf("%lld\n",query(1,1,2*n,b+1,a+n-1).baka);
    else printf("%lld\n",query(1,1,2*n,b+1,a-1).baka);
  }
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ls (x<<1)
#define rs (x<<1|1)
#define N 400005
#define mid ((l+r)>>1)
#define int long long
using namespace std;
const int inf=100000000000007;
struct zero{
  int a,b,baka;
}tree[N<<2];
//2*h[i]-sum[i]
//2*h[i]+sum[i]
// ans
int h[N],sum[N],n,m;
int d[N];
void push_up(int x){
  tree[x]=(zero){max(tree[ls].a,tree[rs].a),max(tree[ls].b,tree[rs].b),max(tree[ls].baka,max(tree[rs].baka,tree[ls].a+tree[rs].b))};
}
void build(int x,int l,int r){
  if(l==r){
    tree[x].a=2*h[l]-sum[l];
    tree[x].b=2*h[l]+sum[l];
    tree[x].baka=-inf;
    // cout<<"fixed:"<<x<<" "<<l<<" "<<r<<" "<<tree[x].a<<" "<<tree[x].b<<endl;
    return;
  }
  build(ls,l,mid);
  build(rs,mid+1,r);
  push_up(x);
  // cout<<"error:"<<x<<" "<<l<<" "<<r<<" "<<tree[x].a<<" "<<tree[x].b<<" "<<tree[x].baka<<endl;
}
zero query(int x,int l,int r,int L,int R){
  // cout<<"query:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<"\n";
  int ans=0;
  zero plk1,plk2;
  plk1.a=plk2.b=plk1.baka=plk2.baka=-2*inf;
  if(L<=l&&r<=R){/* cout<<"GG:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<tree[x].a<<" "<<tree[x].b<<" "<<tree[x].baka<<endl; */return tree[x];}
  if(mid>=L)plk1=query(ls,l,mid,L,R);
  if(mid<R)plk2=query(rs,mid+1,r,L,R);
  // cout<<ls<<" "<<l<<" "<<mid<<" "<<L<<" "
  int a=plk1.baka,b=plk2.baka,c=plk2.b+plk1.a;
  if(a>b&&a>c){ /* cout<<"query1:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<plk1.a<<" "<<plk1.b<<" "<<a<<endl; */return plk1;}
  else if(b>c){ /* cout<<"query2:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<plk2.a<<" " <<plk2.b<<" "<<b<<endl; */return plk2;}
  else { /* cout<<"query3:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<plk1.a<<" "<<plk2.b<<" "<<c<<endl; */ return(zero){plk1.a,plk2.b,plk1.a+plk2.b};}
}
signed main(){
  scanf("%lld%lld",&n,&m);
  for(int i=1;i<=n;i++)scanf("%lld",d+i);
  for(int i=2;i<=n+1;i++)sum[i]=sum[i-1]+d[i-1];
  for(int i=n+2;i<=n*2;i++)sum[i]=sum[i-1]+d[i-n-1];
  for(int i=1;i<=n;i++)scanf("%lld",h+i);
  for(int i=n+1;i<=2*n;i++)h[i]=h[i-n];
  build(1,1,2*n);
  for(int i=1;i<=m;i++){
    int a,b;
    scanf("%lld%lld",&a,&b);
    if(a<=b)printf("%lld\n",query(1,1,2*n,b+1,a+n-1).baka);
    else printf("%lld\n",query(1,1,2*n,b+1,a-1).baka);
  }
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ls (x<<1)
#define rs (x<<1|1)
#define N 400005
#define mid ((l+r)>>1)
#define int long long
using namespace std;
const int inf=1000000007;
struct zero{
  int a,b,baka;
}tree[N<<2];
//2*h[i]-sum[i]
//2*h[i]+sum[i]
// ans
int h[N],sum[N],n,m;
int d[N];
void push_up(int x){
  int a=tree[ls].baka,b=tree[rs].baka,c=tree[rs].b+tree[ls].a;
  if(c>a&&c>b)tree[x]=(zero){tree[ls].a,tree[rs].b,c};
  else if(b>a)tree[x]=tree[rs];
  else tree[x]=tree[ls];
}
void build(int x,int l,int r){
  if(l==r){
    tree[x].a=2*h[l]-sum[l];
    tree[x].b=2*h[l]+sum[l];
    tree[x].baka=-inf;
    // cout<<"fixed:"<<x<<" "<<l<<" "<<r<<" "<<tree[x].a<<" "<<tree[x].b<<endl;
    return;
  }
  build(ls,l,mid);
  build(rs,mid+1,r);
  push_up(x);
  // cout<<"error:"<<x<<" "<<l<<" "<<r<<" "<<tree[x].a<<" "<<tree[x].b<<" "<<tree[x].baka<<endl;
}
zero query(int x,int l,int r,int L,int R){
  // cout<<"query:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" ";
  int ans=0;
  zero plk1,plk2;
  plk1.a=plk2.b=plk1.baka=plk2.baka=-2*inf;
  bool op1=false,op2=false;
  if(L<=l&&r<=R){return tree[x];}
  if(mid>=L)plk1=query(ls,l,mid,L,R),op1=1;
  if(mid<R)plk2=query(rs,mid+1,r,L,R),op2=1;
  // cout<<ls<<" "<<l<<" "<<mid<<" "<<L<<" "
  if(op1&&plk1.baka>plk2.baka&&plk1.baka>(plk2.b+plk1.a)){ return plk1;}
  else if(op2&&plk2.baka>(plk2.b+plk1.a)){ return plk2;}
  else {  return(zero){plk1.a,plk2.b,plk1.a+plk2.b};}
}
signed main(){
  scanf("%lld%lld",&n,&m);
  for(int i=1;i<=n;i++)scanf("%lld",d+i);
  for(int i=2;i<=n+1;i++)sum[i]=sum[i-1]+d[i-1];
  for(int i=n+2;i<=n*2;i++)sum[i]=sum[i-1]+d[i-n-1];
  for(int i=1;i<=n;i++)scanf("%lld",h+i);
  for(int i=n+1;i<=2*n;i++)h[i]=h[i-n];
  build(1,1,2*n);
  for(int i=1;i<=m;i++){
    int a,b;
    scanf("%lld%lld",&a,&b);
    if(a<=b)printf("%lld\n",query(1,1,2*n,b+1,a+n-1).baka);
    else printf("%lld\n",query(1,1,2*n,a+1,b-1).baka);
  }
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ls (x<<1)
#define rs (x<<1|1)
#define N 4000005
#define mid ((l+r)>>1)
#define int long long
using namespace std;
const int inf=100000000000007;
struct zero{
  int a,b,c;
}tree[N<<2];
//2*h[i]-sum[i]
//2*h[i]+sum[i]
// ans
int h[N],sum[N],n,m;
int d[N];
void push_up(int x){
  tree[x]=(zero){max(tree[ls].a,tree[rs].a),max(tree[ls].b,tree[rs].b),max(tree[ls].c,max(tree[rs].c,tree[ls].a+tree[rs].b))};
}
void build(int x,int l,int r){
  if(l==r){
    tree[x].a=2*h[l]-sum[l];
    tree[x].b=2*h[l]+sum[l];
    tree[x].c=-inf;
    // cout<<"fixed:"<<x<<" "<<l<<" "<<r<<" "<<tree[x].a<<" "<<tree[x].b<<endl;
    return;
  }
  build(ls,l,mid);
  build(rs,mid+1,r);
  push_up(x);
  // cout<<"error:"<<x<<" "<<l<<" "<<r<<" "<<tree[x].a<<" "<<tree[x].b<<" "<<tree[x].c<<endl;
}
zero query(int x,int l,int r,int L,int R){
  // cout<<"query:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<"\n";
  int ans=0;
  zero plk1,plk2;
  plk1.a=plk1.b=plk2.a=plk2.b=plk1.c=plk2.c=-2*inf;
  if(L<=l&&r<=R){/* cout<<"GG:"<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<tree[x].a<<" "<<tree[x].b<<" "<<tree[x].c<<endl; */return tree[x];}
  if(mid>=L)plk1=query(ls,l,mid,L,R);
  if(mid<R)plk2=query(rs,mid+1,r,L,R);
  // cout<<ls<<" "<<l<<" "<<mid<<" "<<L<<" "
  // cout<<max(plk1.a,plk2.a)<<" "<<max(plk1.b,plk2.b)<<" "<<max(plk1.c,max(plk2.c,plk1.a+plk2.b))<<endl;
  return (zero){max(plk1.a,plk2.a),max(plk1.b,plk2.b),max(plk1.c,max(plk2.c,plk1.a+plk2.b))};
}
signed main(){
  scanf("%lld%lld",&n,&m);
  for(int i=1;i<=n;i++)scanf("%lld",d+i);
  for(int i=1;i<=n+1;i++)sum[i]=sum[i-1]+d[i-1];
  for(int i=n+2;i<=n*2;i++)sum[i]=sum[i-1]+d[i-n-1];
  for(int i=1;i<=n;i++)scanf("%lld",h+i);
  for(int i=n+1;i<=2*n;i++)h[i]=h[i-n];
  build(1,1,2*n);
  for(int i=1;i<=m;i++){
    int a,b;
    scanf("%lld%lld",&a,&b);
    if(a<=b)printf("%lld\n",query(1,1,2*n,b+1,a+n-1).c);
    else printf("%lld\n",query(1,1,2*n,b+1,a-1).c);
  }
}


#include<bits/stdc++.h>
using namespace std;
#define SIZE 100010
#define INF 0x7fffffff
#define lson (p<<1)
#define rson (p<<1|1)
int n,m;
int h[SIZE],d[SIZE];
struct SegmentTree{
	int l,r;
	int a,b;
	int m;
}tr[SIZE<<2];
void build(int p,int l,int r){
	tr[p].l=l;tr[p].r=r;
	if(tr[p].l==tr[p].r){
		tr[p].a=h[l]+d[l-1];
		tr[p].b=h[l]-d[l-1];
		tr[p].m=-INF;
		return;
	}
	int mid=l+r>>1;
	build(lson,l,mid);
	build(rson,mid+1,r);
	tr[p].a=max(tr[lson].a,tr[rson].a);
	tr[p].b=max(tr[lson].b,tr[rson].b);
	tr[p].m=max(tr[lson].m,max(tr[rson].m,tr[lson].b+tr[rson].a));
	return;
}
SegmentTree ask(int p,int l,int r){
	if(l<=tr[p].l&&tr[p].r<=r) return tr[p];
	SegmentTree R,T;
	R.a=R.b=R.m=-INF;
	T.a=T.b=T.m=-INF;
	int mid=tr[p].l+tr[p].r>>1;
	if(l<=mid) R=ask(lson,l,r);
	if(r>mid) T=ask(rson,l,r);
	T.a=max(T.a,R.a);
	T.b=max(T.b,R.b);
	T.m=max(T.m,max(T.m,R.a+T.b));
	return T;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&d[i]);
		d[n+i]=d[i];
	}
	for(int i=1;i<=n;i++){
		scanf("%d",&h[i]);
		h[i]*=2;
		h[n+i]=h[i];
	}
	for(int i=1;i<=2*n;i++) d[i]+=d[i-1];
	build(1,1,2*n);
	for(int i=1;i<=m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		if(x<=y) printf("%d\n",ask(1,y+1,x+n-1).m);
		else printf("%d\n",ask(1,y+1,x-1).m);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define SIZE 200010
#define int long long
#define lson (p<<1)
#define rson (p<<1|1)
const int INF=1e17;
int n,m;
int h[SIZE],d[SIZE];
struct SegmentTree{
	int l,r;
	int a,b;
	int m;
}tr[SIZE<<2];
void build(int p,int l,int r){
	tr[p].l=l;tr[p].r=r;
	if(tr[p].l==tr[p].r){
		tr[p].a=h[l]+d[l-1];
		tr[p].b=h[l]-d[l-1];
		tr[p].m=-INF;
		return;
	}
	int mid=l+r>>1;
	build(lson,l,mid);
	build(rson,mid+1,r);
	tr[p].a=max(tr[lson].a,tr[rson].a);
	tr[p].b=max(tr[lson].b,tr[rson].b);
	tr[p].m=max(tr[lson].m,max(tr[rson].m,tr[lson].b+tr[rson].a));
	return;
}
SegmentTree ask(int p,int l,int r){
	if(l<=tr[p].l&&tr[p].r<=r) return tr[p];
	int mid=tr[p].l+tr[p].r>>1;
	SegmentTree R,T,QXB;
	R.a=R.b=R.m=-INF;
	T.a=T.b=T.m=-INF;
	QXB.a=QXB.b=QXB.m=-INF;
	if(l<=mid) T=ask(lson,l,r);
	if(r>mid) R=ask(rson,l,r);
	QXB.a=max(T.a,R.a);
	QXB.b=max(T.b,R.b);
	QXB.m=max(T.m,max(R.m,R.a+T.b));
	return QXB;
}
signed main(){
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%lld",&d[i]);
		d[n+i]=d[i];
	}
	for(int i=1;i<=n;i++){
		scanf("%lld",&h[i]);
		h[i]*=2;
		h[n+i]=h[i];
	}
	for(int i=1;i<=2*n;i++) d[i]+=d[i-1];
	build(1,1,2*n);
//	for(int i=1;i<=2*n;i++) cout<<h[i]<<" ";
//	cout<<endl;
//	for(int i=1;i<=2*n;i++) cout<<d[i]<<" ";
//	cout<<endl;
//	for(int i=1;i<=4*n;i++) cout<<tr[i].m<<" "<<tr[i].a<<" "<<tr[i].b<<endl;;
	for(int i=1;i<=m;i++){
		int x,y;
		scanf("%lld%lld",&x,&y);
		if(x<=y) printf("%lld\n",ask(1,y+1,x+n-1).m);
		else printf("%lld\n",ask(1,y+1,x-1).m);
	}
	return 0;
}


#include <bits/stdc++.h>
#define int long long
#define inf 1e18
using namespace std;

int n,q,l,r;
int dis[200005],h[200005],pre[200005];

struct node
{
	int a,b,num;
}tree[800005];

inline void pushup(int rt)
{
	tree[rt].a=max(tree[2*rt].a,tree[2*rt+1].a);
	tree[rt].b=max(tree[2*rt].b,tree[2*rt+1].b);
	tree[rt].num=max(tree[2*rt+1].a+tree[2*rt].b,max(tree[2*rt].num,tree[2*rt+1].num));
}

inline void build_tree(int l,int r,int rt)
{
	if (l==r)
	{
		tree[rt].a=2*h[l]+pre[l-1];
		tree[rt].b=2*h[l]-pre[l-1];
		tree[rt].num=-inf;
		return;
	}
	int mid=(l+r)>>1;

	build_tree(l,mid,2*rt);
	build_tree(mid+1,r,2*rt+1);
	pushup(rt);
}

inline node query(int nl,int nr,int l,int r,int rt)
{
	int mid=(l+r)>>1;
	node a,b,ans;
	a.a=a.b=a.num=b.a=b.b=b.num=ans.a=ans.b=ans.num=-inf;

	if (nl<=l&&r<=nr)  return tree[rt];
	if (nl<=mid)  a=query(nl,nr,l,mid,2*rt);
	if (nr>mid)  b=query(nl,nr,mid+1,r,2*rt+1);

	ans.a=max(a.a,b.a);
	ans.b=max(a.b,b.b);
	ans.num=max(max(a.num,b.num),a.b+b.a);

	return ans;
}

signed main()
{
	cin>>n>>q;
	for (int i=1;i<=n;i++)  cin>>dis[i];
	for (int i=1;i<=n;i++)  cin>>h[i];
	for (int i=n+1;i<=2*n;i++)
	{
		h[i]=h[i-n];
		dis[i]=dis[i-n];
	}
	n*=2;
	for (int i=1;i<=n;i++)  pre[i]=pre[i-1]+dis[i];

	build_tree(1,n,1);
	while (q--)
	{
		cin>>l>>r;
		if (l>r)  r+=n;

		cout<<query(r+1,l+(n/2)-1,1,n,1).num<<endl;
	}
	return 0;
}


#include <bits/stdc++.h>
#define int long long
#define inf 1e18
using namespace std;

int n,q,l,r;
int dis[200005],h[200005],pre[200005];

struct node
{
	int a,b,num;
}tree[800005];

inline void pushup(int rt)
{
	tree[rt].a=max(tree[2*rt].a,tree[2*rt+1].a);
	tree[rt].b=max(tree[2*rt].b,tree[2*rt+1].b);
	tree[rt].num=max(tree[2*rt+1].a+tree[2*rt].b,max(tree[2*rt].num,tree[2*rt+1].num));
}

inline void build_tree(int l,int r,int rt)
{
	if (l==r)
	{
		tree[rt].a=2*h[l]+pre[l-1];
		tree[rt].b=2*h[l]-pre[l-1];
		tree[rt].num=-inf;
		return;
	}
	int mid=(l+r)>>1;

	build_tree(l,mid,2*rt);
	build_tree(mid+1,r,2*rt+1);
	pushup(rt);
}

inline node query(int nl,int nr,int l,int r,int rt)
{
	int mid=(l+r)>>1;
	node a,b,ans;
	a.a=a.b=a.num=b.a=b.b=b.num=ans.a=ans.b=ans.num=-inf;

	if (nl<=l&&r<=nr)  return tree[rt];
	if (nl<=mid)  a=query(nl,nr,l,mid,2*rt);
	if (nr>mid)  b=query(nl,nr,mid+1,r,2*rt+1);

	ans.a=max(a.a,b.a);
	ans.b=max(a.b,b.b);
	ans.num=max(max(a.num,b.num),a.b+b.a);

	return ans;
}

signed main()
{
	cin>>n>>q;
	for (int i=1;i<=n;i++)  cin>>dis[i];
	for (int i=1;i<=n;i++)  cin>>h[i];
	for (int i=n+1;i<=2*n;i++)
	{
		h[i]=h[i-n];
		dis[i]=dis[i-n];
	}
	n*=2;
	for (int i=1;i<=n;i++)  pre[i]=pre[i-1]+dis[i];

	build_tree(1,n,1);
	while (q--)
	{
		cin>>l>>r;
		if (l>r)  r+=(n/2);

		cout<<query(r+1,l+(n/2)-1,1,n,1).num<<endl;
	}
	return 0;
}


#include <bits/stdc++.h>
#define int long long
#define inf 1e18
using namespace std;

int n,q,l,r;
int dis[200005],h[200005],pre[200005];

struct node
{
	int a,b,num;
}tree[800005];

inline void pushup(int rt)
{
	tree[rt].a=max(tree[2*rt].a,tree[2*rt+1].a);
	tree[rt].b=max(tree[2*rt].b,tree[2*rt+1].b);
	tree[rt].num=max(tree[2*rt+1].a+tree[2*rt].b,max(tree[2*rt].num,tree[2*rt+1].num));
}

inline void build_tree(int l,int r,int rt)
{
	if (l==r)
	{
		tree[rt].a=2*h[l]+pre[l-1];
		tree[rt].b=2*h[l]-pre[l-1];
		tree[rt].num=-inf;
		return;
	}
	int mid=(l+r)>>1;

	build_tree(l,mid,2*rt);
	build_tree(mid+1,r,2*rt+1);
	pushup(rt);
}

inline node query(int nl,int nr,int l,int r,int rt)
{
	int mid=(l+r)>>1;
	node a,b,ans;
	a.a=a.b=a.num=b.a=b.b=b.num=ans.a=ans.b=ans.num=-inf;

	if (nl<=l&&r<=nr)  return tree[rt];
	if (nl<=mid)  a=query(nl,nr,l,mid,2*rt);
	if (nr>mid)  b=query(nl,nr,mid+1,r,2*rt+1);

	ans.a=max(a.a,b.a);
	ans.b=max(a.b,b.b);
	ans.num=max(max(a.num,b.num),a.b+b.a);

	return ans;
}

signed main()
{
	cin>>n>>q;
	for (int i=1;i<=n;i++)  cin>>dis[i];
	for (int i=1;i<=n;i++)  cin>>h[i];
	for (int i=n+1;i<=2*n;i++)
	{
		h[i]=h[i-n];
		dis[i]=dis[i-n];
	}
	n*=2;
	for (int i=1;i<=n;i++)  pre[i]=pre[i-1]+dis[i];

	build_tree(1,n,1);
	for (int i=1;i<=2*n;i++)  cout<<"tree:"<<tree[i]<<endl;
	while (q--)
	{
		cin>>l>>r;
		if (l>r)  r+=n;

		cout<<query(r+1,l+(n/2)-1,1,n,1).num<<endl;
	}
	return 0;
}


#include <bits/stdc++.h>
#define int long long
#define inf 2000000007
using namespace std;

int n,q,l,r;
int dis[200005],h[200005],pre[200005];

struct node
{
	int a,b,num;
}tree[800005];

inline void pushup(int rt)
{
	tree[rt].a=max(tree[2*rt].a,tree[2*rt+1].a);
	tree[rt].b=max(tree[2*rt].b,tree[2*rt+1].b);
	tree[rt].num=max(tree[2*rt+1].a+tree[2*rt].b,max(tree[2*rt].num,tree[2*rt+1].num));
}

inline void build_tree(int l,int r,int rt)
{
	if (l==r)
	{
		tree[rt].a=2*h[l]+pre[l-1];
		tree[rt].b=2*h[l]-pre[l-1];
		tree[rt].num=-inf;
		return;
	}
	int mid=(l+r)>>1;

	build_tree(l,mid,2*rt);
	build_tree(mid+1,r,2*rt+1);
	pushup(rt);
}

inline node query(int nl,int nr,int l,int r,int rt)
{
	int mid=(l+r)>>1;
	node a,b,ans;
	a.a=a.b=a.num=b.a=b.b=b.num=ans.a=ans.b=ans.num=-inf;

	if (nl<=l&&r<=nr)  return tree[rt];
	if (nl<=mid)  a=query(nl,nr,l,mid,2*rt);
	if (nr>mid)  b=query(nl,nr,mid+1,r,2*rt+1);

	ans.a=max(a.a,b.a);
	ans.b=max(a.b,b.b);
	ans.num=max(max(a.num,b.num),a.b+b.a);

	return ans;
}

signed main()
{
	cin>>n>>q;
	for (int i=1;i<=n;i++)  cin>>dis[i];
	for (int i=1;i<=n;i++)  cin>>h[i];
	for (int i=n+1;i<=2*n;i++)
	{
		h[i]=h[i-n];
		dis[i]=dis[i-n];
	}
	n*=2;
	for (int i=1;i<=n;i++)  pre[i]=pre[i-1]+dis[i];

	build_tree(1,n,1);

	while (q--)
	{
		cin>>l>>r;
		if (l>r)  r+=n;

		cout<<query(r+1,l+(n/2)-1,1,n,1).num<<endl;
	}
	return 0;
}


/*
 * 此题一看数据范围，考虑log做法。线段树
主要是区间如何合并的问题，爬树问题两个区间合并成一个区间时，最优区间有两种情况
 1）来自左边子区间或者右边子区间，
 2）跨左右两个子区间，所以线段树中要存区间最优解，然后考虑如何处理跨区间问题。
 两颗树之间的距离不好表示成区间最大或者最小值，我们考虑把距离d(x,y)转化一下，变成dy-dx，
 这里di表示第i棵树到第一颗树的距离，然后待求式子变为2hx+2hy+dy-dx=2hy+dy-(-2hx+dx)，
 就只跟单点有关了，然后注意到求最大值只要让前面的最大，后面的最小即可。
所以线段树中要维护三个量：区间最优值，区间最大值2hy+dy，区间最小值-2hx+dx
合并的时候区间最优值三个中间取最优：左右子区间最优；后面区间的最大值减前面区间的最小值
区间最大值和最小值合并就取max和min就行了
线段树维护好了，直接查询就行了。

 */
#include <cstdio>
#include <algorithm>
#include <climits>

using namespace std;
typedef long long ll;
const ll MAXN = 200005;
ll h[MAXN], d[MAXN], pre[MAXN];
struct Node {
    ll a, ma, mi;//区间最优值，区间最大值2hy+dy，区间最小值-2hx+dx
} t[MAXN * 4];

inline ll lc(ll p) { return p << 1; }

inline ll rc(ll p) { return p << 1 | 1; }

Node mergeNode(const Node &l, const Node &r) {
    Node n;
    n.a = max(l.a, max(r.a, r.ma - l.mi));
    n.ma = max(l.ma, r.ma);
    n.mi = min(l.mi, r.mi);
    return n;
}

void pushUp(ll p) {
    t[p] = mergeNode(t[lc(p)], t[rc(p)]);
}

void buildTree(ll p, ll l, ll r) {
    if (l == r) {
        t[p].ma = 2 * h[l] + pre[l];
        t[p].mi = -2 * h[l] + pre[l];
        return;
    }
    int mid = (l + r) / 2;
    buildTree(lc(p), l, mid);
    buildTree(rc(p), mid + 1, r);
    pushUp(p);
}

Node query(ll p, ll l, ll r, ll ql, ll qr) {
    if (ql <= l && r <= qr) {
        return t[p];
    }
    int mid = (l + r) / 2;
    Node n;
    bool hasLeft = false;
    if (ql <= mid) {
        n = query(lc(p), l, mid, ql, qr);
        hasLeft = true;
    }
    if (mid < qr) {
        if (hasLeft) {
            n = mergeNode(n, query(rc(p), mid + 1, r, ql, qr));
        } else {
            n = query(rc(p), mid + 1, r, ql, qr);
        }
    }
    return n;
}

int main() {
    ll n, m;
    scanf("%lld%lld", &n, &m);
    for (ll i = 1; i <= n; ++i) {
        scanf("%lld", &d[i]);
        d[i + n] = d[i];//扩大一倍，化环为链
    }
    for (int i = 1; i <= 2 * n; ++i) {
        pre[i] = pre[i - 1] + d[i - 1];
    }
    for (ll i = 1; i <= n; ++i) {
        scanf("%lld", &h[i]);
        h[i + n] = h[i];
    }
    buildTree(1, 1, n * 2);
    while (m--) {
        ll l, r, a, b;
        scanf("%lld%lld", &a, &b);
        if (a <= b) {
            l = b + 1;
            r = a - 1 + n;
        } else {
            l = b + 1;
            r = a - 1;
        }
        Node ans = query(1, 1, n * 2, l, r);
        printf("%lld\n", ans.a);
    }
    return 0;
}


/*
 * 此题一看数据范围，考虑log做法。线段树
主要是区间如何合并的问题，爬树问题两个区间合并成一个区间时，最优区间有两种情况
 1）来自左边子区间或者右边子区间，
 2）跨左右两个子区间，所以线段树中要存区间最优解，然后考虑如何处理跨区间问题。
 两颗树之间的距离不好表示成区间最大或者最小值，我们考虑把距离d(x,y)转化一下，变成dy-dx，
 这里di表示第i棵树到第一颗树的距离，然后待求式子变为2hx+2hy+dy-dx=2hy+dy-(-2hx+dx)，
 就只跟单点有关了，然后注意到求最大值只要让前面的最大，后面的最小即可。
所以线段树中要维护三个量：区间最优值，区间最大值2hy+dy，区间最小值-2hx+dx
合并的时候区间最优值三个中间取最优：左右子区间最优；后面区间的最大值减前面区间的最小值
区间最大值和最小值合并就取max和min就行了
线段树维护好了，直接查询就行了。

 */
#include <cstdio>
#include <algorithm>
#include <climits>

using namespace std;
typedef long long ll;
const ll MAXN = 200005;
ll h[MAXN], d[MAXN], pre[MAXN];
struct Node {
    ll a, ma, mi;//区间最优值，区间最大值2hy+dy，区间最小值-2hx+dx
} t[MAXN * 4];

inline ll lc(ll p) { return p << 1; }

inline ll rc(ll p) { return p << 1 | 1; }

Node mergeNode(const Node &l, const Node &r) {
    Node n;
    n.a = max(l.a, max(r.a, r.ma - l.mi));
    n.ma = max(l.ma, r.ma);
    n.mi = min(l.mi, r.mi);
    return n;
}

void pushUp(ll p) {
    t[p] = mergeNode(t[lc(p)], t[rc(p)]);
}

void buildTree(ll p, ll l, ll r) {
    if (l == r) {
        t[p].ma = 2 * h[l] + pre[l];
        t[p].mi = -2 * h[l] + pre[l];
        return;
    }
    int mid = (l + r) / 2;
    buildTree(lc(p), l, mid);
    buildTree(rc(p), mid + 1, r);
    pushUp(p);
}

Node query(ll p, ll l, ll r, ll ql, ll qr) {
    if (ql <= l && r <= qr) {
        return t[p];
    }
    int mid = (l + r) / 2;
    Node n;
    bool hasLeft = false;
    if (ql <= mid) {
        n = query(lc(p), l, mid, ql, qr);
        hasLeft = true;
    }
    if (mid < qr) {
        if (hasLeft) {
            n = mergeNode(n, query(rc(p), mid + 1, r, ql, qr));
        } else {
            n = query(rc(p), mid + 1, r, ql, qr);
        }
    }
    return n;
}

int main() {
    ll n, m;
    scanf("%lld%lld", &n, &m);
    for (ll i = 1; i <= n; ++i) {
        scanf("%lld", &d[i]);
        d[i + n] = d[i];//扩大一倍，化环为链
    }
    for (int i = 1; i <= 2 * n; ++i) {
        pre[i] = pre[i - 1] + d[i - 1];
    }
    for (ll i = 1; i <= n; ++i) {
        scanf("%lld", &h[i]);
        h[i + n] = h[i];
    }
    buildTree(1, 1, n * 2);
    while (m--) {
        ll l, r, a, b;
        scanf("%lld%lld", &a, &b);
        if (a <= b) {
            l = b + 1;
            r = a - 1 + n;
        } else {
            l = a + 1;
            r = b - 1;
        }
        Node ans = query(1, 1, n * 2, l, r);
        printf("%lld\n", ans.a);
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn = 3e5 + 50;
ll d[maxn],h[maxn];
struct node
{
    int l,r;
    ll sum,lmax,rmax,maxx;
}tree[maxn << 2];
void push_up(int i)
{
    int x1 = tree[i << 1].l,y1 = tree[i << 1].r;
    int x2 = tree[i << 1 | 1].l,y2 = tree[i << 1 | 1].r;
    ll dis = d[y1];

    /*ll maxx = max(tree[i << 1].lmax,tree[i << 1].sum + h[x1] + h[x2] + dis);

    now.lmax = max(maxx,tree[i << 1].sum + tree[i << 1 | 1].lmax - h[x2] + h[x1] + dis);

    maxx = max(tree[i << 1 | 1].rmax,tree[i << 1 | 1].sum + h[y2] + h[y1]);

    now.rmax = max(maxx,tree[i << 1 | 1].sum + tree[i << 1].rmax - h[y1] + h[y2]);

    now.sum = tree[i << 1].sum + tree[i << 1 | 1].sum;

    maxx = max(tree[i << 1].maxx,tree[i << 1 | 1].maxx);
    maxx = max(maxx,h[y1] + h[x2] + dis);
    maxx = max(now.lmax,now.rmax);

    now.maxx = max(maxx,tree[i << 1].rmax + tree[i << 1 | 1].lmax - h[y1] - h[x2]);*/

    ll mx = 0;

    ll maxx = max(tree[i << 1].lmax,h[x1] + tree[i << 1].sum + h[x2] + dis);

    tree[i].lmax = max(maxx,tree[i << 1].sum + tree[i << 1 | 1].lmax - h[x2] + h[x1] + dis);
    mx = max(mx,tree[i].lmax);

    maxx = max(tree[i << 1 | 1].rmax,h[y2] + tree[i << 1 | 1].sum + h[y1] + dis);

    tree[i].rmax = max(maxx,tree[i << 1 | 1].sum + tree[i << 1].rmax + h[y2] - h[y1] + dis);
    mx = max(mx,tree[i].rmax);

    mx = max(mx,max(tree[i << 1].maxx,tree[i << 1 | 1].maxx));
    mx = max(mx,h[x2] + h[y1] + dis);
    mx = max(mx,h[x1] + h[y2] + tree[i << 1].sum + tree[i << 1 | 1].sum + dis);
    tree[i].maxx = max(mx,tree[i << 1].rmax + tree[i << 1 | 1].lmax - h[x2] - h[y1] + dis);

    tree[i].sum = tree[i << 1].sum + tree[i << 1 | 1].sum + dis;
}
void build(int i,int l,int r)
{
    tree[i].l = l;
    tree[i].r = r;
    int mid = (l + r) >> 1;
    if (l == r)
    {
        tree[i].lmax = tree[i].rmax = tree[i].maxx = h[l];
        tree[i].sum = 0;
        return;
    }
    build(i << 1,l,mid);
    build(i << 1 | 1,mid + 1,r);
    push_up(i);
}
node query(int i,int x,int y)
{
    if (tree[i].l >= x && tree[i].r <= y) return tree[i];
    int mid = (tree[i].l + tree[i].r) >> 1;
    if (y <= mid) return query(i << 1,x,y);
    else if (x > mid) return query(i << 1 | 1,x,y);
    else
    {
        node lt = query(i << 1,x,mid);
        node rt = query(i << 1 | 1,mid + 1,y);
        node now;
        int x1 = lt.l,y1 = lt.r;
        int x2 = rt.l,y2 = rt.r;
        ll mx = 0;
        ll dis = d[y1];

        ll maxx = max(lt.lmax,h[x1] + lt.sum + h[x2] + dis);

        now.lmax = max(maxx,lt.sum + rt.lmax - h[x2] + h[x1] + dis);
        mx = max(mx,now.lmax);

        maxx = max(rt.rmax,h[y2] + rt.sum + h[y1] + dis);

        now.rmax = max(maxx,rt.sum + lt.rmax + h[y2] - h[y1] + dis);
        mx = max(mx,now.rmax);

        mx = max(mx,max(lt.maxx,rt.maxx));
        mx = max(mx,h[x2] + h[y1] + dis);
        mx = max(mx,h[x1] + h[y2] + lt.sum + rt.sum + dis);
        now.maxx = max(mx,lt.rmax + rt.lmax - h[x2] - h[y1] + dis);

        now.sum = lt.sum + rt.sum + dis;
        now.l = lt.l;
        now.r = rt.r;
        return now;
    }
}
int main()
{
    int n,q;
    scanf("%d%d",&n,&q);
    for (int i = 1 ; i <= n ; i ++)
    {
        scanf("%lld",&d[i]);
    }
    for (int i = 1 ; i <= n ; i ++)
    {
        scanf("%lld",&h[i]);
        h[i] *= 2;
    }
    for (int i = n + 1 ; i <= 2 * n ; i ++)
    {
        d[i] = d[i - n];
        h[i] = h[i - n];
    }
    int m = n;
    n *= 2;
    build(1,1,n);
    //cout<<"??  "<<tree[1].maxx<<endl;
    while(q --)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        if (x > y)
        {
            int x1 = y + 1;
            int y1 = x - 1;
            x = x1;
            y = y1;
        }
        else
        {
            int x1 = y + 1;
            int y1 = x + m - 1;
            x = x1;
            y = y1;
        }
        //cout<<"? "<<x<<"  "<<y<<endl;
        node res = query(1,x,y);
        printf("%lld\n",res.maxx);
    }
}