#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
///Welcome to Nasif's Code
#define bug printf("bug\n");
#define bug2(var) cout<<#var<<" "<<var<<endl;
#define co(q) cout<<q<<endl;
#define all(q) (q).begin(),(q).end()
#define pi acos(-1)
#define inf 1000000000000000LL
#define FastRead    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define MODADD(ADD_X,ADD_Y)  (ADD_X+ADD_Y)%MOD
#define MODSUB(SUB_X,SUB_Y)  ((SUB_X-SUB_Y)+MOD)%MOD
#define MODMUL(MUL_X,MUL_Y)  (MUL_X*MUL_Y)%MOD
#define LCM(LCM_X,LCM_Y) (LCM_X/__gcd(LCM_X,LCM_Y))*LCM_Y
template <typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
typedef long long int ll;
typedef unsigned long long int ull;
const int MOD = (int)1e9+7;
const int MAX = 1e6;
int dx[]= {1,0,-1,0,1,-1,1,-1};
int dy[]= {0,1,0,-1,1,-1,-1,1};
int rem[MAX],sp[MAX];
vector<int >adj[MAX];
bool cmp(pair<int,int> &l,pair<int,int> &r)
{
    if(l.first<r.first)
        return 1;
    if(l.first>r.first)
        return 0;
    if(l.second<r.second)
        return 1;
    return 0;
}
int parent[MAX+50];
int root(int child)
{
    while(parent[child]!=child)
    {
        parent[child]=parent[parent[child]];
        child=parent[child];
    }
    return child;
}
void node_union(int x,int y)
{
    int a=root(x);
    int b=root(y);
    parent[max(a,b)]=parent[min(a,b)];
}
int main()
{
    FastRead
    //freopen("output.txt", "w", stdout);
    int n,m;
    cin>>n>>m;
    for(int i=1; i<=n; i++)
        parent[i]=i;
    for(int i=0; i<m; i++)
    {
        int u,v;
        cin>>u>>v;
        if(u>v)
            swap(u,v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    set<int>st,s;
    stack<int>order;
    for(int i=1; i<=n; i++)
    {
        st.insert(i);
        order.push(i);
    }
    while(!order.empty())
    {
        int i=order.top();
        order.pop();
        map<int,int>mp;
        for(auto it:adj[i])
        {
            mp[it]=1;
        }
        vector<int>v;
        for(auto it:st)
        {
            if(!mp[it])
            {
                node_union(i,it);
                v.push_back(it);
            }
        }
        for(auto it:v)
        {
            order.push(it);
            st.erase(it);
        }
        if(st.empty())
            break;
    }

    for(int i=1; i<=n; i++)
    {
        s.insert(parent[i]);
    }
    cout<<s.size()-1<<endl;

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=200200,inf=1e9;
ll tree[4*N],a[N],lazy[4*N];
void push(int nd,int l,int r)
{
    if(lazy[nd])
    {
        tree[nd]+=lazy[nd];
        if(l!=r){
        lazy[2*nd]+=lazy[nd];
        lazy[2*nd+1]+=lazy[nd];
        }
        lazy[nd]=0;
    }
}
void build(int nd,int l,int r)
{
    if(l==r)
        {
            tree[nd]=a[l];
            return;
        }
    int mid=(l+r)/2;
    build(2*nd,l,mid);
    build(2*nd+1,mid+1,r);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
}
void upd(int nd,int l,int r,int from,int to,int val)
{
    push(nd,l,r);
    if(from>r||to<l)
        return;
    if(from<=l&&to>=r)
    {
        tree[nd]+=val;
        lazy[2*nd]+=val;
        lazy[2*nd+1]+=val;
        return;
    }
    int mid=(l+r)/2;
    upd(2*nd,l,mid,from,to,val);
    upd(2*nd+1,mid+1,r,from,to,val);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
    return;
}
ll qry(int nd,int l,int r,int from ,int to)
{
    push(nd,l,r);
    if(from>r||to<l)
        return inf;
    if(from<=l&&r<=to)
    return tree[nd];
    int mid=(l+r)/2;
    ll A=qry(2*nd,l,mid,from,to);
    ll B=qry(2*nd+1,mid+1,r,from,to);
    return min(A,B);
}
int main()
{
   int n,m;
   cin>>n;
   for(int i=0;i<n;i++)
    cin>>a[i];
   build(1,0,n-1);
   cin>>m;
   while(m--)
   {

       int l,r;
       char c;
       scanf("%d %d",&l,&r);
       scanf("%c",&c);
       if(c == '\n')
       {
           if(l<=r)
           {
               cout<<qry(1,0,n-1,l,r)<<endl;
           }
           else {
            ll ans=qry(1,0,n-1,l,n-1);
            ll b=qry(1,0,n-1,0,r);
            cout<<min(ans,b)<<endl;
           }
       }
       else{
        ll val;
        cin>>val;
        if(l<=r)
        {
            upd(1,0,n-1,l,r,val);
        }
        else{
            upd(1,0,n-1,l,n-1,val);
            upd(1,0,n-1,0,r,val);
        }
       }
   }

return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=200200,inf=1e9;
ll tree[4*N],a[N],lazy[4*N];
void push(int nd,int l,int r)
{
    if(lazy[nd])
    {
        tree[nd]+=lazy[nd];
        if(l!=r){
        lazy[2*nd]+=lazy[nd];
        lazy[2*nd+1]+=lazy[nd];
        }
        lazy[nd]=0;
    }
}
void build(int nd,int l,int r)
{
    if(l==r)
        {
            tree[nd]=a[l];
            return;
        }
    int mid=(l+r)/2;
    build(2*nd,l,mid);
    build(2*nd+1,mid+1,r);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
}
void upd(int nd,int l,int r,int from,int to,int val)
{
    push(nd,l,r);
    if(from>r||to<l)
        return;
    if(from<=l&&to>=r)
    {
        tree[nd]+=val;
        tree[2*nd]+=val;
        tree[2*nd+1]+=val;
        return;
    }
    int mid=(l+r)/2;
    upd(2*nd,l,mid,from,to,val);
    upd(2*nd+1,mid+1,r,from,to,val);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
    return;
}
ll qry(int nd,int l,int r,int from ,int to)
{
    push(nd,l,r);
    if(from>r||to<l)
        return inf;
    if(from<=l&&r<=to)
    return tree[nd];
    int mid=(l+r)/2;
    ll A=qry(2*nd,l,mid,from,to);
    ll B=qry(2*nd+1,mid+1,r,from,to);
    return min(A,B);
}
int main()
{
   int n,m;
   cin>>n;
   for(int i=0;i<n;i++)
    cin>>a[i];
   build(1,0,n-1);
   cin>>m;
   while(m--)
   {

       int l,r;
       char c;
       scanf("%d %d",&l,&r);
       scanf("%c",&c);
       if(c == '\n')
       {
           if(l<=r)
           {
               cout<<qry(1,0,n-1,l,r)<<endl;
           }
           else {
            ll ans=qry(1,0,n-1,l,n-1);
            ll b=qry(1,0,n-1,0,r);
            cout<<min(ans,b)<<endl;
           }
       }
       else{
        ll val;
        cin>>val;
        if(l<=r)
        {
            upd(1,0,n-1,l,r,val);
        }
        else{
            upd(1,0,n-1,l,n-1,val);
            upd(1,0,n-1,0,r,val);
        }
       }
   }

return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=200200;
const ll inf=1ll<<60;
ll tree[4*N],a[N],lazy[4*N];
void push(int nd,int l,int r)
{
    if(lazy[nd])
    {
        tree[nd]+=lazy[nd];
        if(l!=r){
        lazy[2*nd]+=lazy[nd];
        lazy[2*nd+1]+=lazy[nd];
        }
        lazy[nd]=0;
    }
}
void build(int nd,int l,int r)
{
    if(l==r)
        {
            tree[nd]=a[l];
            return;
        }
    int mid=(l+r)/2;
    build(2*nd,l,mid);
    build(2*nd+1,mid+1,r);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
}
void upd(int nd,int l,int r,int from,int to,int val)
{
    push(nd,l,r);
    if(from>r||to<l)
        return;
    if(from<=l&&to>=r)
    {
        tree[nd]+=val;
        lazy[2*nd]+=val;
        lazy[2*nd+1]+=val;
        return;
    }
    int mid=(l+r)/2;
    upd(2*nd,l,mid,from,to,val);
    upd(2*nd+1,mid+1,r,from,to,val);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
    return;
}
ll qry(int nd,int l,int r,int from ,int to)
{
    push(nd,l,r);
    if(from>r||to<l)
        return inf;
    if(from<=l&&r<=to)
    return tree[nd];
    int mid=(l+r)/2;
    ll A=qry(2*nd,l,mid,from,to);
    ll B=qry(2*nd+1,mid+1,r,from,to);
    return min(A,B);
}
int main()
{
   int n,m;
   cin>>n;
   for(int i=0;i<n;i++)
    cin>>a[i];
   build(1,0,n-1);
   cin>>m;
   while(m--)
   {

       int l,r;
       char c;
       scanf("%d %d",&l,&r);
       scanf("%c",&c);
       if(c == '\n')
       {
           if(l<=r)
           {
               cout<<qry(1,0,n-1,l,r)<<endl;
           }
           else {
            ll ans=qry(1,0,n-1,l,n-1);
            ll b=qry(1,0,n-1,0,r);
            cout<<min(ans,b)<<endl;
           }
       }
       else{
        ll val;
        cin>>val;
        if(l<=r)
        {
            upd(1,0,n-1,l,r,val);
        }
        else{
            upd(1,0,n-1,l,n-1,val);
            upd(1,0,n-1,0,r,val);
        }
       }
   }

return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=200200;
const int inf=1ll<<60;
ll a[N];
ll tree[N*4];
ll lazy[N*4];
int n , m ;
void build(int nd,int l,int r)
{
    if(l==r)
    {
        tree[nd]=a[l];
        return;
    }
    int mid=(l+r)/2;
    build(2*nd,l,mid);
    build(2*nd+1,mid+1,r);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
    return;
}
void push(int nd,int l,int r)
{
    if(lazy[nd])
    {
         tree[nd]+=lazy[nd];
    if(l!=r)
        {
            lazy[2*nd]+=lazy[nd];
            lazy[2*nd+1]+=lazy[nd];
        }
        lazy[nd]=0;
    }

}
void update(int nd,int l,int r,int from,int to,int val)
{
    push(nd,l,r);
    if(from>r||to<l)
        return;
    if(l>=from&&to>=r)
    {
        tree[nd]+=val;
        lazy[2*nd]+=val;
    lazy[2*nd+1]+=val;
        return;
    }
    int mid=(l+r)/2;
    update(2*nd,l,mid,from,to,val);
    update(2*nd+1,mid+1,r,from,to,val);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
}
ll qry(int nd,int l,int r,int from,int to)
{
    push(nd,l,r);
    if(r<from||l>to)
        return inf;
    if(l>=from&&r<=to)
    return tree[nd];
    int mid=(l+r)/2;
    ll A=qry(2*nd,l,mid,from,to);
    ll B=qry(2*nd+1,mid+1,r,from,to);
    return min(A,B);
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%I64d",a+i);
build(1,0,n-1);

scanf("%d",&m);
while( m-- ){

int l , r ;
ll val;
scanf("%d %d",&l,&r);
char c;
scanf("%c",&c);

if( c == '\n' ){

if( l<=r )printf("%I64d\n",qry(1,0,n-1,l,r));
else{
    ll A = qry(1,0,n-1,l,n-1);
    ll B = qry(1,0,n-1,0,r);
    printf("%I64d\n",min(A,B));
}

}else{
scanf("%I64d",&val);

if( l <= r )update(1,0,n-1,l,r,val);
else{
    update(1,0,n-1,l,n-1,val);
    update(1,0,n-1,0,r,val);
}

}

}

return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+5;
const ll inf=1ll<<60;
ll a[N];
ll tree[N*4];
ll lazy[N*4];
int n , m ;
void build(int nd,int l,int r)
{
    if(l==r)
    {
        tree[nd]=a[l];
        return;
    }
    int mid=(l+r)/2;
    build(2*nd,l,mid);
    build(2*nd+1,mid+1,r);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
    return;
}
void push(int nd,int l,int r)
{
    if(lazy[nd])
    {
         tree[nd]+=lazy[nd];
    if(l!=r)
        {
            lazy[2*nd]+=lazy[nd];
            lazy[2*nd+1]+=lazy[nd];
        }
        lazy[nd]=0;
    }

}
void update(int nd,int l,int r,int from,int to,int val)
{
    push(nd,l,r);
    if(from>r||to<l)
        return;
    if(l>=from&&to>=r)
    {
        tree[nd]+=val;
        lazy[2*nd]+=val;
    lazy[2*nd+1]+=val;
        return;
    }
    int mid=(l+r)/2;
    update(2*nd,l,mid,from,to,val);
    update(2*nd+1,mid+1,r,from,to,val);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
}
ll qry(int nd,int l,int r,int from,int to)
{
    push(nd,l,r);
    if(r<from||l>to)
        return inf;
    if(l>=from&&r<=to)
    return tree[nd];
    int mid=(l+r)/2;
    ll A=qry(2*nd,l,mid,from,to);
    ll B=qry(2*nd+1,mid+1,r,from,to);
    return min(A,B);
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%I64d",a+i);
build(1,0,n-1);

scanf("%d",&m);
while( m-- ){

int l , r ;
ll val;
scanf("%d %d",&l,&r);
char c;
scanf("%c",&c);

if( c == '\n' ){

if( l<=r )printf("%I64d\n",qry(1,0,n-1,l,r));
else{
    ll A = qry(1,0,n-1,l,n-1);
    ll B = qry(1,0,n-1,0,r);
    printf("%I64d\n",min(A,B));
}

}else{
scanf("%I64d",&val);

if( l <= r )update(1,0,n-1,l,r,val);
else{
    update(1,0,n-1,l,n-1,val);
    update(1,0,n-1,0,r,val);
}

}

}

return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+5;
const ll inf=1ll<<60;
ll tree[4*N],a[N],lazy[4*N];
void push(int nd,int l,int r)
{
    if(lazy[nd])
    {
        tree[nd]+=lazy[nd];
        if(l!=r){
        lazy[2*nd]+=lazy[nd];
        lazy[2*nd+1]+=lazy[nd];
        }
        lazy[nd]=0;
    }
}
void build(int nd,int l,int r)
{
    if(l==r)
        {
            tree[nd]=a[l];
            return;
        }
    int mid=(l+r)/2;
    build(2*nd,l,mid);
    build(2*nd+1,mid+1,r);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
}
void upd(int nd,int l,int r,int from,int to,int val)
{
    push(nd,l,r);
    if(from>r||to<l)
        return;
    if(from<=l&&to>=r)
    {
        tree[nd]+=val;
        lazy[2*nd]+=val;
        lazy[2*nd+1]+=val;
        return;
    }
    int mid=(l+r)/2;
    upd(2*nd,l,mid,from,to,val);
    upd(2*nd+1,mid+1,r,from,to,val);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
    return;
}
ll qry(int nd,int l,int r,int from ,int to)
{
    push(nd,l,r);
    if(from>r||to<l)
        return inf;
    if(from<=l&&r<=to)
    return tree[nd];
    int mid=(l+r)/2;
    ll A=qry(2*nd,l,mid,from,to);
    ll B=qry(2*nd+1,mid+1,r,from,to);
    return min(A,B);
}
int main()
{
   int n,m;
   scanf("%d",&n);
   for(int i=0;i<n;i++)
    scanf("%lld",a+i);
   build(1,0,n-1);
   scanf("%d",&m);
   while(m--)
   {

       int l,r;
       char c;
       scanf("%d %d",&l,&r);
       scanf("%c",&c);
       if(c == '\n')
       {
           if(l<=r)
           {
               printf("%lld \n",qry(1,0,n-1,l,r));
           }
           else {
            ll ans=qry(1,0,n-1,l,n-1);
            ll b=qry(1,0,n-1,0,r);
            printf("%lld \n",min(ans,b));
           }
       }
       else{
        ll val;
        scanf("%lld",&val);
        if(l<=r)
        {
            upd(1,0,n-1,l,r,val);
        }
        else{
            upd(1,0,n-1,l,n-1,val);
            upd(1,0,n-1,0,r,val);
        }
       }
   }

return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=200200;
const ll inf=1e16;
ll a[N];
ll tree[N*4];
ll lazy[N*4];
int n , m ;
void build(int nd,int l,int r)
{
    if(l==r)
    {
        tree[nd]=a[l];
        return;
    }
    int mid=(l+r)/2;
    build(2*nd,l,mid);
    build(2*nd+1,mid+1,r);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
    return;
}
void push(int nd,int l,int r)
{
    if(lazy[nd])
    {
         tree[nd]+=lazy[nd];
    if(l!=r)
        {
            lazy[2*nd]+=lazy[nd];
            lazy[2*nd+1]+=lazy[nd];
        }
        lazy[nd]=0;
    }

}
void update(int nd,int l,int r,int from,int to,int val)
{
    push(nd,l,r);
    if(from>r||to<l)
        return;
    if(l>=from&&to>=r)
    {
        tree[nd]+=val;
        lazy[2*nd]+=val;
    lazy[2*nd+1]+=val;
        return;
    }
    int mid=(l+r)/2;
    update(2*nd,l,mid,from,to,val);
    update(2*nd+1,mid+1,r,from,to,val);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
}
ll qry(int nd,int l,int r,int from,int to)
{
    push(nd,l,r);
    if(r<from||l>to)
        return inf;
    if(l>=from&&r<=to)
    return tree[nd];
    int mid=(l+r)/2;
    ll A=qry(2*nd,l,mid,from,to);
    ll B=qry(2*nd+1,mid+1,r,from,to);
    return min(A,B);
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%I64d",a+i);
build(1,0,n-1);

scanf("%d",&m);
while( m-- ){

int l , r ;
ll val;
scanf("%d %d",&l,&r);
char c;
scanf("%c",&c);

if( c == '\n' ){

if( l<=r )printf("%I64d\n",qry(1,0,n-1,l,r));
else{
    ll A = qry(1,0,n-1,l,n-1);
    ll B = qry(1,0,n-1,0,r);
    printf("%I64d\n",min(A,B));
}

}else{
scanf("%I64d",&val);

if( l <= r )update(1,0,n-1,l,r,val);
else{
    update(1,0,n-1,l,n-1,val);
    update(1,0,n-1,0,r,val);
}

}

}

return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=200200,inf=1ll<<60;
ll tree[4*N],a[N],lazy[4*N];
void push(int nd,int l,int r)
{
    if(lazy[nd])
    {
        tree[nd]+=lazy[nd];
        if(l!=r){
        lazy[2*nd]+=lazy[nd];
        lazy[2*nd+1]+=lazy[nd];
        }
        lazy[nd]=0;
    }
}
void build(int nd,int l,int r)
{
    if(l==r)
        {
            tree[nd]=a[l];
            return;
        }
    int mid=(l+r)/2;
    build(2*nd,l,mid);
    build(2*nd+1,mid+1,r);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
}
void upd(int nd,int l,int r,int from,int to,int val)
{
    push(nd,l,r);
    if(from>r||to<l)
        return;
    if(from<=l&&to>=r)
    {
        tree[nd]+=val;
        lazy[2*nd]+=val;
        lazy[2*nd+1]+=val;
        return;
    }
    int mid=(l+r)/2;
    upd(2*nd,l,mid,from,to,val);
    upd(2*nd+1,mid+1,r,from,to,val);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
    return;
}
ll qry(int nd,int l,int r,int from ,int to)
{
    push(nd,l,r);
    if(from>r||to<l)
        return inf;
    if(from<=l&&r<=to)
    return tree[nd];
    int mid=(l+r)/2;
    ll A=qry(2*nd,l,mid,from,to);
    ll B=qry(2*nd+1,mid+1,r,from,to);
    return min(A,B);
}
int main()
{
   int n,m;
   cin>>n;
   for(int i=0;i<n;i++)
    cin>>a[i];
   build(1,0,n-1);
   cin>>m;
   while(m--)
   {

       int l,r;
       char c;
       scanf("%d %d",&l,&r);
       scanf("%c",&c);
       if(c == '\n')
       {
           if(l<=r)
           {
               cout<<qry(1,0,n-1,l,r)<<endl;
           }
           else {
            ll ans=qry(1,0,n-1,l,n-1);
            ll b=qry(1,0,n-1,0,r);
            cout<<min(ans,b)<<endl;
           }
       }
       else{
        ll val;
        cin>>val;
        if(l<=r)
        {
            upd(1,0,n-1,l,r,val);
        }
        else{
            upd(1,0,n-1,l,n-1,val);
            upd(1,0,n-1,0,r,val);
        }
       }
   }

return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+5;
const ll inf=1ll<<60;
ll tree[4*N],a[N],lazy[4*N];
void push(int nd,int l,int r)
{
    if(lazy[nd])
    {
        tree[nd]+=lazy[nd];
        if(l!=r){
        lazy[2*nd]+=lazy[nd];
        lazy[2*nd+1]+=lazy[nd];
        }
        lazy[nd]=0;
    }
}
void build(int nd,int l,int r)
{
    if(l==r)
        {
            tree[nd]=a[l];
            return;
        }
    int mid=(l+r)/2;
    build(2*nd,l,mid);
    build(2*nd+1,mid+1,r);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
}
void upd(int nd,int l,int r,int from,int to,int val)
{
    push(nd,l,r);
    if(from>r||to<l)
        return;
    if(from<=l&&to>=r)
    {
        tree[nd]+=val;
        lazy[2*nd]+=val;
        lazy[2*nd+1]+=val;
        return;
    }
    int mid=(l+r)/2;
    upd(2*nd,l,mid,from,to,val);
    upd(2*nd+1,mid+1,r,from,to,val);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
    return;
}
ll qry(int nd,int l,int r,int from ,int to)
{
    push(nd,l,r);
    if(from>r||to<l)
        return inf;
    if(from<=l&&r<=to)
    return tree[nd];
    int mid=(l+r)/2;
    ll A=qry(2*nd,l,mid,from,to);
    ll B=qry(2*nd+1,mid+1,r,from,to);
    return min(A,B);
}
int main()
{
   int n,m;
   cin>>n;
   for(int i=0;i<n;i++)
    cin>>a[i];
   build(1,0,n-1);
   cin>>m;
   while(m--)
   {

       int l,r;
       char c;
       scanf("%d %d",&l,&r);
       scanf("%c",&c);
       if(c == '\n')
       {
           if(l<=r)
           {
               cout<<qry(1,0,n-1,l,r)<<endl;
           }
           else {
            ll ans=qry(1,0,n-1,l,n-1);
            ll b=qry(1,0,n-1,0,r);
            cout<<min(ans,b)<<endl;
           }
       }
       else{
        ll val;
        cin>>val;
        if(l<=r)
        {
            upd(1,0,n-1,l,r,val);
        }
        else{
            upd(1,0,n-1,l,n-1,val);
            upd(1,0,n-1,0,r,val);
        }
       }
   }

return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=200200,inf=1e9;
ll tree[4*N],a[N],lazy[4*N];
void push(int nd,int l,int r)
{
    if(lazy[nd])
    {
        tree[nd]+=lazy[nd];
        if(l!=r){
        lazy[2*nd]+=lazy[nd];
        lazy[2*nd+1]+=lazy[nd];
        }
        lazy[nd]=0;
    }
}
void build(int nd,int l,int r)
{
    if(l==r)
        {
            tree[nd]=a[l];
            return;
        }
    int mid=(l+r)/2;
    build(2*nd,l,mid);
    build(2*nd+1,mid+1,r);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
}
void upd(int nd,int l,int r,int from,int to,int val)
{
    push(nd,l,r);
    if(from>r||to<l)
        return;
    if(from<=l&&to>=r)
    {
        tree[nd]+=val;
        tree[2*nd]+=val;
        tree[2*nd+1]+=val;
        return;
    }
    int mid=(l+r)/2;
    upd(2*nd,l,mid,from,to,val);
    upd(2*nd+1,mid+1,r,from,to,val);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
    return;
}
ll qry(int nd,int l,int r,int from ,int to)
{
    push(nd,l,r);
    if(from>r||to<l)
        return inf;
    if(from<=l&&r<=to)
    return tree[nd];
    int mid=(l+r)/2;
    ll A=qry(2*nd,l,mid,from,to);
    ll B=qry(2*nd+1,mid+1,r,from,to);
    return min(A,B);
}
int main()
{
   int n,m;
   cin>>n;
   for(int i=1;i<=n;i++)
    cin>>a[i];
   build(1,1,n);
   cin>>m;
   while(m--)
   {

       int l,r;
       char c;
       scanf("%d %d",&l,&r);
       scanf("%c",&c);
       if(c == '\n')
       {
           if(l<=r)
           {
               cout<<qry(1,1,n,l,r)<<endl;
           }
           else {
            ll ans=min(qry(1,1,n,l,n),qry(1,1,n,1,r));
            cout<<ans<<endl;
           }
       }
       else{
        ll val;
        cin>>val;
        if(l<=r)
        {
            upd(1,1,n,l,r,val);
        }
        else{
            upd(1,1,n,l,n,val);
            upd(1,1,n,1,r,val);
        }
       }
   }

return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=200200;
const ll inf=1ll<<60;
ll a[N];
ll tree[N*4];
ll lazy[N*4];
int n , m ;
void build(int nd,int l,int r)
{
    if(l==r)
    {
        tree[nd]=a[l];
        return;
    }
    int mid=(l+r)/2;
    build(2*nd,l,mid);
    build(2*nd+1,mid+1,r);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
    return;
}
void push(int nd,int l,int r)
{
    if(lazy[nd])
    {
         tree[nd]+=lazy[nd];
    if(l!=r)
        {
            lazy[2*nd]+=lazy[nd];
            lazy[2*nd+1]+=lazy[nd];
        }
        lazy[nd]=0;
    }

}
void update(int nd,int l,int r,int from,int to,int val)
{
    push(nd,l,r);
    if(from>r||to<l)
        return;
    if(l>=from&&to>=r)
    {
        tree[nd]+=val;
        lazy[2*nd]+=val;
    lazy[2*nd+1]+=val;
        return;
    }
    int mid=(l+r)/2;
    update(2*nd,l,mid,from,to,val);
    update(2*nd+1,mid+1,r,from,to,val);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
}
ll qry(int nd,int l,int r,int from,int to)
{
    push(nd,l,r);
    if(r<from||l>to)
        return inf;
    if(l>=from&&r<=to)
    return tree[nd];
    int mid=(l+r)/2;
    ll A=qry(2*nd,l,mid,from,to);
    ll B=qry(2*nd+1,mid+1,r,from,to);
    return min(A,B);
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%I64d",a+i);
build(1,0,n-1);

scanf("%d",&m);
while( m-- ){

int l , r ;
ll val;
scanf("%d %d",&l,&r);
char c;
scanf("%c",&c);

if( c == '\n' ){

if( l<=r )printf("%I64d\n",qry(1,0,n-1,l,r));
else{
    ll A = qry(1,0,n-1,l,n-1);
    ll B = qry(1,0,n-1,0,r);
    printf("%I64d\n",min(A,B));
}

}else{
scanf("%I64d",&val);

if( l <= r )update(1,0,n-1,l,r,val);
else{
    update(1,0,n-1,l,n-1,val);
    update(1,0,n-1,0,r,val);
}

}

}

return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+5;
const ll inf=1ll<<60;
ll tree[4*N],a[N],lazy[4*N];
void push(int nd,int l,int r)
{
    if(lazy[nd])
    {
        tree[nd]+=lazy[nd];
        if(l!=r){
        lazy[2*nd]+=lazy[nd];
        lazy[2*nd+1]+=lazy[nd];
        }
        lazy[nd]=0;
    }
}
void build(int nd,int l,int r)
{
    if(l==r)
        {
            tree[nd]=a[l];
            return;
        }
    int mid=(l+r)/2;
    build(2*nd,l,mid);
    build(2*nd+1,mid+1,r);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
}
void upd(int nd,int l,int r,int from,int to,int val)
{
    push(nd,l,r);
    if(from>r||to<l)
        return;
    if(from<=l&&to>=r)
    {
        tree[nd]+=val;
        lazy[2*nd]+=val;
        lazy[2*nd+1]+=val;
        return;
    }
    int mid=(l+r)/2;
    upd(2*nd,l,mid,from,to,val);
    upd(2*nd+1,mid+1,r,from,to,val);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
    return;
}
ll qry(int nd,int l,int r,int from ,int to)
{
    push(nd,l,r);
    if(from>r||to<l)
        return inf;
    if(from<=l&&r<=to)
    return tree[nd];
    int mid=(l+r)/2;
    ll A=qry(2*nd,l,mid,from,to);
    ll B=qry(2*nd+1,mid+1,r,from,to);
    return min(A,B);
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
   int n,m;
   cin>>n;
   for(int i=0;i<n;i++)
    cin>>a[i];
   build(1,0,n-1);
   cin>>m;
   while(m--)
   {

       int l,r;
       char c;
       scanf("%d %d",&l,&r);
       scanf("%c",&c);
       if(c == '\n')
       {
           if(l<=r)
           {
               cout<<qry(1,0,n-1,l,r)<<endl;
           }
           else {
            ll ans=qry(1,0,n-1,l,n-1);
            ll b=qry(1,0,n-1,0,r);
            cout<<min(ans,b)<<endl;
           }
       }
       else{
        ll val;
        cin>>val;
        if(l<=r)
        {
            upd(1,0,n-1,l,r,val);
        }
        else{
            upd(1,0,n-1,l,n-1,val);
            upd(1,0,n-1,0,r,val);
        }
       }
   }

return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=200200;
const int inf=1e9;
ll a[N];
ll tree[N*4];
ll lazy[N*4];
int n , m ;
void build(int nd,int l,int r)
{
    if(l==r)
    {
        tree[nd]=a[l];
        return;
    }
    int mid=(l+r)/2;
    build(2*nd,l,mid);
    build(2*nd+1,mid+1,r);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
    return;
}
void push(int nd,int l,int r)
{
    if(lazy[nd])
    {   tree[nd]+=lazy[nd];
    if(l!=r)
        {
            lazy[2*nd]+=lazy[nd];
            lazy[2*nd+1]+=lazy[nd];
        }
        lazy[nd]=0;
    }

}
void update(int nd,int l,int r,int from,int to,int val)
{
    push(nd,l,r);
    if(from>r||to<l)
        return;
    if(l>=from&&to>=r)
    {
        tree[nd]+=val;
        lazy[nd<<1]+=val;
    lazy[nd<<1|1]+=val;
        return;
    }
    int mid=(l+r)/2;
    update(2*nd,l,mid,from,to,val);
    update(2*nd+1,mid+1,r,from,to,val);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
}
ll qry(int nd,int l,int r,int from,int to)
{
    push(nd,l,r);
    if(r<from||l>to)
        return inf;
    if(l>=from&&r<=to)
    return tree[nd];
    int mid=(l+r)/2;
    ll A=qry(2*nd,l,mid,from,to);
    ll B=qry(2*nd+1,mid+1,r,from,to);
    return min(A,B);
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%I64d",a+i);
build(1,0,n-1);

scanf("%d",&m);
while( m-- ){

int l , r ;
ll val;
scanf("%d %d",&l,&r);
char c;
scanf("%c",&c);

if( c == '\n' ){

if( l<=r )printf("%I64d\n",qry(1,0,n-1,l,r));
else{
    ll A = qry(1,0,n-1,l,n-1);
    ll B = qry(1,0,n-1,0,r);
    printf("%I64d\n",min(A,B));
}

}else{
scanf("%I64d",&val);

if( l <= r )update(1,0,n-1,l,r,val);
else{
    update(1,0,n-1,l,n-1,val);
    update(1,0,n-1,0,r,val);
}

}

}

return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=200200;
const int inf=1e9;
ll a[100006];
ll tree[N*4];
ll lazy[N*4];
int n , m ;
void build(int nd,int l,int r)
{
    if(l==r)
    {
        tree[nd]=a[l];
        return;
    }
    int mid=(l+r)/2;
    build(2*nd,l,mid);
    build(2*nd+1,mid+1,r);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
    return;
}
void push(int nd,int l,int r)
{
    if(lazy[nd])
    {   tree[nd]+=lazy[nd];
    if(l!=r)
        {
            lazy[2*nd]+=lazy[nd];
            lazy[2*nd+1]+=lazy[nd];
        }
        lazy[nd]=0;
    }

}
void update(int nd,int l,int r,int from,int to,int val)
{
    push(nd,l,r);
    if(from>r||to<l)
        return;
    if(l>=from&&to>=r)
    {
        tree[nd]+=val;
        lazy[nd<<1]+=val;
    lazy[nd<<1|1]+=val;
        return;
    }
    int mid=(l+r)/2;
    update(2*nd,l,mid,from,to,val);
    update(2*nd+1,mid+1,r,from,to,val);
    tree[nd]=min(tree[2*nd],tree[2*nd+1]);
}
ll qry(int nd,int l,int r,int from,int to)
{
    push(nd,l,r);
    if(r<from||l>to)
        return inf;
    if(l>=from&&r<=to)
    return tree[nd];
    int mid=(l+r)/2;
    ll A=qry(2*nd,l,mid,from,to);
    ll B=qry(2*nd+1,mid+1,r,from,to);
    return min(A,B);
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%I64d",a+i);
build(1,0,n-1);

scanf("%d",&m);
while( m-- ){

int l , r ;
ll val;
scanf("%d %d",&l,&r);
char c;
scanf("%c",&c);

if( c == '\n' ){

if( l<=r )printf("%I64d\n",qry(1,0,n-1,l,r));
else{
    ll A = qry(1,0,n-1,l,n-1);
    ll B = qry(1,0,n-1,0,r);
    printf("%I64d\n",min(A,B));
}

}else{
scanf("%I64d",&val);

if( l <= r )update(1,0,n-1,l,r,val);
else{
    update(1,0,n-1,l,n-1,val);
    update(1,0,n-1,0,r,val);
}

}

}

return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define F first
#define S second
#define pi 3.14159265359
#define EPS 1e-9
#define MOD 1000000007
void XsliferX(){ios::sync_with_stdio(0);ios_base::sync_with_stdio(0);cin.tie(0),cout.tie(0);}
ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x),y/2);else return (x*f_p((x*x),y/2));}
int dx[9]= {1,-1,0,0,0,1,-1,1,-1};
int dy[9]= {0,0,1,-1,0,1,-1,-1,1};
const int MX=(1<<19);
struct SegmentTree{
    ll tree[2*MX];
    int lazy[2*MX];
    void build(int cur ,int l,int r,vector<int> arr)
    {
        lazy[cur]=1e9;
        if(l==r)
        {
            tree[cur]=arr[l];
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        build(left,l,mid,arr);
        build(right,mid+1,r,arr);
        tree[cur]=min(tree[left],tree[right]);
    }
    void propagate(int i,int l,int r)
    {
        if(lazy[i]==1e9)return;
        tree[i]+=lazy[i];
        if(l!=r)
        {
            if(lazy[i*2]==1e9)lazy[i*2]=lazy[i];
            else lazy[i*2]+=lazy[i];
            if(lazy[i*2+1]==1e9)lazy[i*2+1]=lazy[i];
            else lazy[i*2+1]+=lazy[i];
        }
        lazy[i]=1e9;
    }
    void update(int cur,int l,int r,int a,int b,int val)
    {
        if(lazy[cur]!=1e9)
            propagate(cur,l,r);
        if(a>r||b<l)
            return;
        if(l>=a&&r<=b){
            lazy[cur]=val;
            propagate(cur,l,r);
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        update(left,l,mid,a,b,val);
        update(right,mid+1,r,a,b,val);
        tree[cur]=min(tree[left],tree[right]);
    }
    int getmin(int cur,int l,int r,int a,int b)
    {
        propagate(cur,l,r);
        if(a>r||b<l)return 1e9;
        if(l>=a&&r<=b)return tree[cur];
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        return min(getmin(left,l,mid,a,b),getmin(right,mid+1,r,a,b));
    }
}d;
int n,m;
vector<int> arr;
int main()
{
    //XsliferX();
    cin>>n;
    arr.resize(n+1);
    for(int i=0 ; i<n ; i++)cin>>arr[i];
    d.build(1,0,n-1,arr);
    cin>>m;
    cin.ignore();
     string s;
    stringstream ss;
    vector<int> v(4);
    int counter=0;
    int x;
    for(int i=0;i<m;i++)
    {
       getline(cin,s);
        ss.clear();
        counter=0;
        ss<<s;
        while(ss>>x)
        {
            v[counter]=x;
            counter++;
        }
        if(counter==2)
        {
            if(v[0]<=v[1])
            cout << d.getmin(1,0,n-1,v[0],v[1])<< '\n';
            else
            {
                cout << min(d.getmin(1,0,n-1,v[0],n-1),d.getmin(1,0,n-1,0,v[1]))<< '\n';
            }
        }
        else
        {
            if(v[0]<=v[1])
            {
                d.update(1,0,n-1,v[0],v[1],v[2]);
            }
            else
            {
                d.update(1,0,n-1,v[0],n-1,v[2]);
                d.update(1,0,n-1,0,v[1],v[2]);
            }
        }
    }
    return 0;
}
/*a=97  A=65
z=122 Z=90
0=48
prime number of ones in their binary representation
*/
// for(int i=0 ; i<n ; i++)
//ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x)%MOD,y/2);else return (x*f_p((x*x)%MOD,y/2))%MOD;}
//freopen("output.txt","w",stdout);


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define F first
#define S second
#define pi 3.14159265359
#define EPS 1e-9
#define MOD 1000000007
void XsliferX(){ios::sync_with_stdio(0);ios_base::sync_with_stdio(0);cin.tie(0),cout.tie(0);}
ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x),y/2);else return (x*f_p((x*x),y/2));}
int dx[9]= {1,-1,0,0,0,1,-1,1,-1};
int dy[9]= {0,0,1,-1,0,1,-1,-1,1};
const int MX=(1<<19);
struct SegmentTree{
    ll tree[2*MX];
    int lazy[2*MX];
    void build(int cur ,int l,int r,vector<int> arr)
    {
        lazy[cur]=1e9;
        if(l==r)
        {
            tree[cur]=arr[l];
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        build(left,l,mid,arr);
        build(right,mid+1,r,arr);
        tree[cur]=min(tree[left],tree[right]);
    }
    void propagate(int i,int l,int r)
    {
        if(lazy[i]==1e9)return;
        tree[i]+=lazy[i];
        if(l!=r)
        {
            if(lazy[i*2]==1e9)lazy[i*2]=lazy[i];
            else lazy[i*2]+=lazy[i];
            if(lazy[i*2+1]==1e9)lazy[i*2+1]=lazy[i];
            else lazy[i*2+1]+=lazy[i];
        }
        lazy[i]=1e9;
    }
    void update(int cur,int l,int r,int a,int b,int val)
    {
        if(lazy[cur]!=1e9)
            propagate(cur,l,r);
        if(a>r||b<l)
            return;
        if(l>=a&&r<=b){
            lazy[cur]=val;
            propagate(cur,l,r);
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        update(left,l,mid,a,b,val);
        update(right,mid+1,r,a,b,val);
        tree[cur]=min(tree[left],tree[right]);
    }
    int getmin(int cur,int l,int r,int a,int b)
    {
        propagate(cur,l,r);
        if(a>r||b<l)return 1e9;
        if(l>=a&&r<=b)return tree[cur];
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        return min(getmin(left,l,mid,a,b),getmin(right,mid+1,r,a,b));
    }
}d;
int n,m;
vector<int> arr;
int main()
{
    //XsliferX();
    cin>>n;
    arr.resize(n+1);
    for(int i=0 ; i<n ; i++)scanf("%d",&arr[i]);
    d.build(1,0,n-1,arr);
    cin>>m;
    cin.ignore();
     string s;
    stringstream ss;
    vector<int> v(4);
    int counter=0;
    int x;
    for(int i=0;i<m;i++)
    {
       getline(cin,s);
        ss.clear();
        counter=0;
        ss<<s;
        while(ss>>x)
        {
            v[counter]=x;
            counter++;
        }
        if(counter==2)
        {
            int ans;
            if(v[0]<=v[1])
            ans=d.getmin(1,0,n-1,v[0],v[1]);
            else
            {
                ans=min(d.getmin(1,0,n-1,v[0],n-1),d.getmin(1,0,n-1,0,v[1]));
            }
            printf("%d\n",ans);
        }
        else
        {
            if(v[0]<=v[1])
            {
                d.update(1,0,n-1,v[0],v[1],v[2]);
            }
            else
            {
                d.update(1,0,n-1,v[0],n-1,v[2]);
                d.update(1,0,n-1,0,v[1],v[2]);
            }
        }
    }
    return 0;
}
/*a=97  A=65
z=122 Z=90
0=48
prime number of ones in their binary representation
*/
// for(int i=0 ; i<n ; i++)
//ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x)%MOD,y/2);else return (x*f_p((x*x)%MOD,y/2))%MOD;}
//freopen("output.txt","w",stdout);


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define F first
#define S second
#define pi 3.14159265359
#define EPS 1e-9
#define MOD 1000000007
void XsliferX(){ios::sync_with_stdio(0);ios_base::sync_with_stdio(0);cin.tie(0),cout.tie(0);}
ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x),y/2);else return (x*f_p((x*x),y/2));}
int dx[9]= {1,-1,0,0,0,1,-1,1,-1};
int dy[9]= {0,0,1,-1,0,1,-1,-1,1};
const int MX=(1<<19);
struct SegmentTree{
    ll tree[2*MX];
    int lazy[2*MX];
    void build(int cur ,int l,int r,vector<int> arr)
    {
        lazy[cur]=1e9;
        if(l==r)
        {
            tree[cur]=arr[l];
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        build(left,l,mid,arr);
        build(right,mid+1,r,arr);
        tree[cur]=min(tree[left],tree[right]);
    }
    void propagate(int i,int l,int r)
    {
        if(lazy[i]==1e9)return;
        tree[i]+=lazy[i];
        if(l!=r)
        {
            if(lazy[i*2]==1e9)lazy[i*2]=lazy[i];
            else lazy[i*2]+=lazy[i];
            if(lazy[i*2+1]==1e9)lazy[i*2+1]=lazy[i];
            else lazy[i*2+1]+=lazy[i];
        }
        lazy[i]=1e9;
    }
    void update(int cur,int l,int r,int a,int b,int val)
    {
        if(lazy[cur]!=1e9)
            propagate(cur,l,r);
        if(a>r||b<l)
            return;
        if(l>=a&&r<=b){
            lazy[cur]=val;
            propagate(cur,l,r);
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        update(left,l,mid,a,b,val);
        update(right,mid+1,r,a,b,val);
        tree[cur]=min(tree[left],tree[right]);
    }
    int getmin(int cur,int l,int r,int a,int b)
    {
        propagate(cur,l,r);
        if(a>r||b<l)return 1e9;
        if(l>=a&&r<=b)return tree[cur];
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        return min(getmin(left,l,mid,a,b),getmin(right,mid+1,r,a,b));
    }
}d;
int n,m;
vector<int> arr;
int main()
{
    XsliferX();
    cin>>n;
    arr.resize(n+1);
    for(int i=0 ; i<n ; i++)cin>>arr[i];
    d.build(1,0,n-1,arr);
    cin>>m;
    cin.ignore();
     string s;
    stringstream ss;
    vector<int> v(4);
    int counter=0;
    int x;
    for(int i=0;i<m;i++)
    {
       getline(cin,s);
        ss.clear();
        counter=0;
        ss<<s;
        while(ss>>x)
        {
            v[counter]=x;
            counter++;
        }
        if(counter==2)
        {
            if(v[0]<=v[1])
            cout << d.getmin(1,0,n-1,v[0],v[1])<< '\n';
            else
            {
                cout << min(d.getmin(1,0,n-1,v[0],n-1),d.getmin(1,0,n-1,0,v[1]))<< '\n';
            }
        }
        else
        {
            if(v[0]<=v[1])
            {
                d.update(1,0,n-1,v[0],v[1],v[2]);
            }
            else
            {
                d.update(1,0,n-1,v[0],n-1,v[2]);
                d.update(1,0,n-1,0,v[1],v[2]);
            }
        }
    }
    return 0;
}
/*a=97  A=65
z=122 Z=90
0=48
prime number of ones in their binary representation
*/
// for(int i=0 ; i<n ; i++)
//ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x)%MOD,y/2);else return (x*f_p((x*x)%MOD,y/2))%MOD;}
//freopen("output.txt","w",stdout);


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define F first
#define S second
#define pi 3.14159265359
#define EPS 1e-9
#define MOD 1000000007
void XsliferX(){ios::sync_with_stdio(0);ios_base::sync_with_stdio(0);cin.tie(0),cout.tie(0);}
ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x),y/2);else return (x*f_p((x*x),y/2));}
int dx[9]= {1,-1,0,0,0,1,-1,1,-1};
int dy[9]= {0,0,1,-1,0,1,-1,-1,1};
const int MX=(1<<19);
struct SegmentTree{
    ll tree[2*MX];
    ll lazy[2*MX];
    void build(int cur ,int l,int r,vector<int> arr)
    {
        if(l==r)
        {
            tree[cur]=arr[l];
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        build(left,l,mid,arr);
        build(right,mid+1,r,arr);
        tree[cur]=min(tree[left],tree[right]);
    }
    void propagate(int i,int l,int r)
    {
        if(lazy[i]==0)return;
        tree[i]+=lazy[i];
        if(l!=r)
        {
            lazy[i*2]+=lazy[i];
            lazy[i*2+1]+=lazy[i];
        }
        lazy[i]=0;
    }
    void update(int cur,int l,int r,int a,int b,int val)
    {
        propagate(cur,l,r);
        if(a>r||b<l)
            return;
        if(l>=a&&r<=b){
            lazy[cur]=val;
            propagate(cur,l,r);
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        update(left,l,mid,a,b,val);
        update(right,mid+1,r,a,b,val);
        tree[cur]=min(tree[left],tree[right]);
    }
    ll getmin(int cur,int l,int r,int a,int b)
    {
        propagate(cur,l,r);
        if(a>r||b<l)return 1e9;
        if(l>=a&&r<=b)return tree[cur];
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        return min(getmin(left,l,mid,a,b),getmin(right,mid+1,r,a,b));
    }
}d;
int n,m;
vector<int> arr;
int main()
{
    //XsliferX();
    cin>>n;
    arr.resize(n+1);
    for(int i=0 ; i<n ; i++)scanf("%d",&arr[i]);
    d.build(1,0,n-1,arr);
    cin>>m;
    cin.ignore();
     string s;
    stringstream ss;
    vector<int> v(4);
    int counter=0;
    int x;
    for(int i=0;i<m;i++)
    {
       getline(cin,s);
        ss.clear();
        counter=0;
        ss<<s;
        while(ss>>x)
        {
            v[counter]=x;
            counter++;
        }
        if(counter==2)
        {
            ll ans;
            if(v[0]<=v[1])
            ans=d.getmin(1,0,n-1,v[0],v[1]);
            else
            {
                ans=min(d.getmin(1,0,n-1,v[0],n-1),d.getmin(1,0,n-1,0,v[1]));
            }
            printf("%I64d\n",ans);
        }
        else
        {
            if(v[0]<=v[1])
            {
                d.update(1,0,n-1,v[0],v[1],v[2]);
            }
            else
            {
                d.update(1,0,n-1,v[0],n-1,v[2]);
                d.update(1,0,n-1,0,v[1],v[2]);
            }
        }
    }
    return 0;
}
/*a=97  A=65
z=122 Z=90
0=48
prime number of ones in their binary representation
*/
// for(int i=0 ; i<n ; i++)
//ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x)%MOD,y/2);else return (x*f_p((x*x)%MOD,y/2))%MOD;}
//freopen("output.txt","w",stdout);


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define F first
#define S second
#define pi 3.14159265359
#define EPS 1e-9
#define MOD 1000000007
void XsliferX(){ios::sync_with_stdio(0);ios_base::sync_with_stdio(0);cin.tie(0),cout.tie(0);}
ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x),y/2);else return (x*f_p((x*x),y/2));}
int dx[9]= {1,-1,0,0,0,1,-1,1,-1};
int dy[9]= {0,0,1,-1,0,1,-1,-1,1};
const int MX=(1<<19);
struct SegmentTree{
    ll tree[2*MX];
    int lazy[2*MX];
    void build(int cur ,int l,int r,vector<int> arr)
    {
        lazy[cur]=1e9;
        if(l==r)
        {
            tree[cur]=arr[l];
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        build(left,l,mid,arr);
        build(right,mid+1,r,arr);
        tree[cur]=min(tree[left],tree[right]);
    }
    void propagate(int i,int l,int r)
    {
        if(lazy[i]==1e9)return;
        tree[i]+=lazy[i];
        if(l!=r)
            lazy[i*2]=lazy[i*2+1]=lazy[i];
        lazy[i]=1e9;
    }
    void update(int cur,int l,int r,int a,int b,int val)
    {
        if(lazy[cur]!=1e9)
            propagate(cur,l,r);
        if(a>r||b<l)
            return;
        if(l>=a&&r<=b){
            lazy[cur]=val;
            propagate(cur,l,r);
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        update(left,l,mid,a,b,val);
        update(right,mid+1,r,a,b,val);
        tree[cur]=min(tree[left],tree[right]);
    }
    int getsum(int cur,int l,int r,int a,int b)
    {
        propagate(cur,l,r);
        if(a>r||b<l)return 0;
        if(l>=a&&r<=b)return tree[cur];
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        return getsum(left,l,mid,a,b)+getsum(right,mid+1,r,a,b);
    }
}d;
int n,m;
vector<int> arr;
int main()
{
    XsliferX();
    cin>>n;
    arr.resize(n+1);
    for(int i=0 ; i<n ; i++)cin>>arr[i];
    d.build(1,0,n-1,arr);
    cin>>m;
    cin.ignore();
     string s;
    stringstream ss;
    vector<int> v(4);
    int counter=0;
    int x;
    for(int i=0;i<m;i++)
    {
       getline(cin,s);
        ss.clear();
        counter=0;
        ss<<s;
        while(ss>>x)
        {
            v[counter]=x;
            counter++;
        }
        if(counter==2)
        {
            if(v[0]<=v[1])
            cout << d.getsum(1,0,n-1,v[0],v[1])<< '\n';
            else
            {
                cout << min(d.getsum(1,0,n-1,v[0],n-1),d.getsum(1,0,n-1,0,v[1]))<< '\n';
            }
        }
        else
        {
            if(v[0]<=v[1])
            {
                d.update(1,0,n-1,v[0],v[1],v[2]);
            }
            else
            {
                d.update(1,0,n-1,v[0],n-1,v[2]);
                d.update(1,0,n-1,0,v[1],v[2]);
            }
        }
    }
    return 0;
}
/*a=97  A=65
z=122 Z=90
0=48
prime number of ones in their binary representation
*/
// for(int i=0 ; i<n ; i++)
//ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x)%MOD,y/2);else return (x*f_p((x*x)%MOD,y/2))%MOD;}
//freopen("output.txt","w",stdout);


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define F first
#define S second
#define pi 3.14159265359
#define EPS 1e-9
#define MOD 1000000007
void XsliferX(){ios::sync_with_stdio(0);ios_base::sync_with_stdio(0);cin.tie(0),cout.tie(0);}
ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x),y/2);else return (x*f_p((x*x),y/2));}
int dx[9]= {1,-1,0,0,0,1,-1,1,-1};
int dy[9]= {0,0,1,-1,0,1,-1,-1,1};
const int MX=(1<<19);
struct SegmentTree{
    ll tree[2*MX];
    int lazy[2*MX];
    void build(int cur ,int l,int r,vector<int> arr)
    {
        lazy[cur]=1e9;
        if(l==r)
        {
            tree[cur]=arr[l];
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        build(left,l,mid,arr);
        build(right,mid+1,r,arr);
        tree[cur]=min(tree[left],tree[right]);
    }
    void propagate(int i,int l,int r)
    {
        if(lazy[i]==1e9)return;
        tree[i]+=lazy[i];
        if(l!=r)
            lazy[i*2]=lazy[i*2+1]=lazy[i];
        lazy[i]=1e9;
    }
    void update(int cur,int l,int r,int a,int b,int val)
    {
        if(lazy[cur]!=1e9)
            propagate(cur,l,r);
        if(a>r||b<l)
            return;
        if(l>=a&&r<=b){
            lazy[cur]=val;
            propagate(cur,l,r);
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        update(left,l,mid,a,b,val);
        update(right,mid+1,r,a,b,val);
        tree[cur]=min(tree[left],tree[right]);
    }
    int getsum(int cur,int l,int r,int a,int b)
    {
        propagate(cur,l,r);
        if(a>r||b<l)return 1e9;
        if(l>=a&&r<=b)return tree[cur];
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        return min(getsum(left,l,mid,a,b),getsum(right,mid+1,r,a,b));
    }
}d;
int n,m;
vector<int> arr;
int main()
{
    //XsliferX();
    cin>>n;
    arr.resize(n+1);
    for(int i=0 ; i<n ; i++)cin>>arr[i];
    d.build(1,0,n-1,arr);
    cin>>m;
    cin.ignore();
     string s;
    stringstream ss;
    vector<int> v(4);
    int counter=0;
    int x;
    for(int i=0;i<m;i++)
    {
       getline(cin,s);
        ss.clear();
        counter=0;
        ss<<s;
        while(ss>>x)
        {
            v[counter]=x;
            counter++;
        }
        if(counter==2)
        {
            if(v[0]<=v[1])
            cout << d.getsum(1,0,n-1,v[0],v[1])<< '\n';
            else
            {
                cout << min(d.getsum(1,0,n-1,v[0],n-1),d.getsum(1,0,n-1,0,v[1]))<< '\n';
            }
        }
        else
        {
            if(v[0]<=v[1])
            {
                d.update(1,0,n-1,v[0],v[1],v[2]);
            }
            else
            {
                d.update(1,0,n-1,v[0],n-1,v[2]);
                d.update(1,0,n-1,0,v[1],v[2]);
            }
        }
    }
    return 0;
}
/*a=97  A=65
z=122 Z=90
0=48
prime number of ones in their binary representation
*/
// for(int i=0 ; i<n ; i++)
//ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x)%MOD,y/2);else return (x*f_p((x*x)%MOD,y/2))%MOD;}
//freopen("output.txt","w",stdout);


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define F first
#define S second
#define pi 3.14159265359
#define EPS 1e-9
#define MOD 1000000007
void XsliferX(){ios::sync_with_stdio(0);ios_base::sync_with_stdio(0);cin.tie(0),cout.tie(0);}
ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x),y/2);else return (x*f_p((x*x),y/2));}
int dx[9]= {1,-1,0,0,0,1,-1,1,-1};
int dy[9]= {0,0,1,-1,0,1,-1,-1,1};
const int MX=(1<<19);
struct SegmentTree{
    ll tree[2*MX];
    int lazy[2*MX];
    void build(int cur ,int l,int r,vector<int> arr)
    {
        lazy[cur]=1e9;
        if(l==r)
        {
            tree[cur]=arr[l];
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        build(left,l,mid,arr);
        build(right,mid+1,r,arr);
        tree[cur]=min(tree[left],tree[right]);
    }
    void propagate(int i,int l,int r)
    {
        if(lazy[i]==1e9)return;
        tree[i]+=lazy[i];
        if(l!=r)
        {
            if(lazy[i*2]==1e9)lazy[i*2]=lazy[i];
            else lazy[i*2]+=lazy[i];
            if(lazy[i*2+1]==1e9)lazy[i*2+1]=lazy[i];
            else lazy[i*2+1]+=lazy[i];
        }
        lazy[i]=1e9;
    }
    void update(int cur,int l,int r,int a,int b,int val)
    {
        if(lazy[cur]!=1e9)
            propagate(cur,l,r);
        if(a>r||b<l)
            return;
        if(l>=a&&r<=b){
            lazy[cur]=val;
            propagate(cur,l,r);
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        update(left,l,mid,a,b,val);
        update(right,mid+1,r,a,b,val);
        tree[cur]=min(tree[left],tree[right]);
    }
    ll getmin(int cur,int l,int r,int a,int b)
    {
        propagate(cur,l,r);
        if(a>r||b<l)return 1e9;
        if(l>=a&&r<=b)return tree[cur];
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        return min(getmin(left,l,mid,a,b),getmin(right,mid+1,r,a,b));
    }
}d;
int n,m;
vector<int> arr;
int main()
{
    //XsliferX();
    cin>>n;
    arr.resize(n+1);
    for(int i=0 ; i<n ; i++)scanf("%d",&arr[i]);
    d.build(1,0,n-1,arr);
    cin>>m;
    cin.ignore();
     string s;
    stringstream ss;
    vector<int> v(4);
    int counter=0;
    int x;
    for(int i=0;i<m;i++)
    {
       getline(cin,s);
        ss.clear();
        counter=0;
        ss<<s;
        while(ss>>x)
        {
            v[counter]=x;
            counter++;
        }
        if(counter==2)
        {
            ll ans;
            if(v[0]<=v[1])
            ans=d.getmin(1,0,n-1,v[0],v[1]);
            else
            {
                ans=min(d.getmin(1,0,n-1,v[0],n-1),d.getmin(1,0,n-1,0,v[1]));
            }
            printf("%I64d\n",ans);
        }
        else
        {
            if(v[0]<=v[1])
            {
                d.update(1,0,n-1,v[0],v[1],v[2]);
            }
            else
            {
                d.update(1,0,n-1,v[0],n-1,v[2]);
                d.update(1,0,n-1,0,v[1],v[2]);
            }
        }
    }
    return 0;
}
/*a=97  A=65
z=122 Z=90
0=48
prime number of ones in their binary representation
*/
// for(int i=0 ; i<n ; i++)
//ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x)%MOD,y/2);else return (x*f_p((x*x)%MOD,y/2))%MOD;}
//freopen("output.txt","w",stdout);


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define F first
#define S second
#define pi 3.14159265359
#define EPS 1e-9
#define MOD 1000000007
void XsliferX(){ios::sync_with_stdio(0);ios_base::sync_with_stdio(0);cin.tie(0),cout.tie(0);}
ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x),y/2);else return (x*f_p((x*x),y/2));}
int dx[9]= {1,-1,0,0,0,1,-1,1,-1};
int dy[9]= {0,0,1,-1,0,1,-1,-1,1};
const int MX=(1<<19);
vector<int> arr;
struct SegmentTree{
    ll tree[2*MX];
    ll lazy[2*MX];
    void build(int cur ,int l,int r)
    {
        if(l==r)
        {
            tree[cur]=arr[l];
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        build(left,l,mid);
        build(right,mid+1,r);
        tree[cur]=min(tree[left],tree[right]);
    }
    void propagate(int i,int l,int r)
    {
        if(lazy[i]==0)return;
        tree[i]+=lazy[i];
        if(l!=r)
        {
            lazy[i*2]+=lazy[i];
            lazy[i*2+1]+=lazy[i];
        }
        lazy[i]=0;
    }
    void update(int cur,int l,int r,int a,int b,int val)
    {
        propagate(cur,l,r);
        if(a>r||b<l)
            return;
        if(l>=a&&r<=b){
            lazy[cur]=val;
            propagate(cur,l,r);
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        update(left,l,mid,a,b,val);
        update(right,mid+1,r,a,b,val);
        tree[cur]=min(tree[left],tree[right]);
    }
    ll getmin(int cur,int l,int r,int a,int b)
    {
        propagate(cur,l,r);
        if(a>r||b<l)return 1e9;
        if(l>=a&&r<=b)return tree[cur];
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        return min(getmin(left,l,mid,a,b),getmin(right,mid+1,r,a,b));
    }
}d;
int n,m;
int main()
{
    //XsliferX();
    cin>>n;
    arr.resize(n+1);
    for(int i=0 ; i<n ; i++)scanf("%d",&arr[i]);
    d.build(1,0,n-1);
    cin>>m;
    cin.ignore();
     string s;
    stringstream ss;
    vector<int> v(4);
    int counter=0;
    int x;
    for(int i=0;i<m;i++)
    {
       getline(cin,s);
        ss.clear();
        counter=0;
        ss<<s;
        while(ss>>x)
        {
            v[counter]=x;
            counter++;
        }
        if(counter==2)
        {
            ll ans;
            if(v[0]<=v[1])
            ans=d.getmin(1,0,n-1,v[0],v[1]);
            else
            {
                ans=min(d.getmin(1,0,n-1,v[0],n-1),d.getmin(1,0,n-1,0,v[1]));
            }
            printf("%I64d\n",ans);
        }
        else
        {
            if(v[0]<=v[1])
            {
                d.update(1,0,n-1,v[0],v[1],v[2]);
            }
            else
            {
                d.update(1,0,n-1,v[0],n-1,v[2]);
                d.update(1,0,n-1,0,v[1],v[2]);
            }
        }
    }
    return 0;
}
/*a=97  A=65
z=122 Z=90
0=48
prime number of ones in their binary representation
*/
// for(int i=0 ; i<n ; i++)
//ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x)%MOD,y/2);else return (x*f_p((x*x)%MOD,y/2))%MOD;}
//freopen("output.txt","w",stdout);


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define F first
#define S second
#define pi 3.14159265359
#define EPS 1e-9
#define MOD 1000000007
void XsliferX(){ios::sync_with_stdio(0);ios_base::sync_with_stdio(0);cin.tie(0),cout.tie(0);}
ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x),y/2);else return (x*f_p((x*x),y/2));}
int dx[9]= {1,-1,0,0,0,1,-1,1,-1};
int dy[9]= {0,0,1,-1,0,1,-1,-1,1};
const int MX=(1<<19);
struct SegmentTree{
    ll tree[2*MX];
    int lazy[2*MX];
    void build(int cur ,int l,int r,vector<int> arr)
    {
        lazy[cur]=1e9;
        if(l==r)
        {
            tree[cur]=arr[l];
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        build(left,l,mid,arr);
        build(right,mid+1,r,arr);
        tree[cur]=min(tree[left],tree[right]);
    }
    void propagate(int i,int l,int r)
    {
        if(lazy[i]==1e9)return;
        tree[i]+=lazy[i];
        if(l!=r)
        {
            if(lazy[i*2]==-1e15)lazy[i*2]=lazy[i];
            else lazy[i*2]+=lazy[i];
            if(lazy[i*2+1]==-1e15)lazy[i*2+1]=lazy[i];
            else lazy[i*2+1]+=lazy[i];
        }
        lazy[i]=1e9;
    }
    void update(int cur,int l,int r,int a,int b,int val)
    {
        if(lazy[cur]!=1e9)
            propagate(cur,l,r);
        if(a>r||b<l)
            return;
        if(l>=a&&r<=b){
            lazy[cur]=val;
            propagate(cur,l,r);
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        update(left,l,mid,a,b,val);
        update(right,mid+1,r,a,b,val);
        tree[cur]=min(tree[left],tree[right]);
    }
    int getmin(int cur,int l,int r,int a,int b)
    {
        propagate(cur,l,r);
        if(a>r||b<l)return 1e9;
        if(l>=a&&r<=b)return tree[cur];
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        return min(getmin(left,l,mid,a,b),getmin(right,mid+1,r,a,b));
    }
}d;
int n,m;
vector<int> arr;
int main()
{
    //XsliferX();
    cin>>n;
    arr.resize(n+1);
    for(int i=0 ; i<n ; i++)cin>>arr[i];
    d.build(1,0,n-1,arr);
    cin>>m;
    cin.ignore();
     string s;
    stringstream ss;
    vector<int> v(4);
    int counter=0;
    int x;
    for(int i=0;i<m;i++)
    {
       getline(cin,s);
        ss.clear();
        counter=0;
        ss<<s;
        while(ss>>x)
        {
            v[counter]=x;
            counter++;
        }
        if(counter==2)
        {
            if(v[0]<=v[1])
            cout << d.getmin(1,0,n-1,v[0],v[1])<< '\n';
            else
            {
                cout << min(d.getmin(1,0,n-1,v[0],n-1),d.getmin(1,0,n-1,0,v[1]))<< '\n';
            }
        }
        else
        {
            if(v[0]<=v[1])
            {
                d.update(1,0,n-1,v[0],v[1],v[2]);
            }
            else
            {
                d.update(1,0,n-1,v[0],n-1,v[2]);
                d.update(1,0,n-1,0,v[1],v[2]);
            }
        }
    }
    return 0;
}
/*a=97  A=65
z=122 Z=90
0=48
prime number of ones in their binary representation
*/
// for(int i=0 ; i<n ; i++)
//ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x)%MOD,y/2);else return (x*f_p((x*x)%MOD,y/2))%MOD;}
//freopen("output.txt","w",stdout);


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define F first
#define S second
#define pi 3.14159265359
#define EPS 1e-9
#define MOD 1000000007
void XsliferX(){ios::sync_with_stdio(0);ios_base::sync_with_stdio(0);cin.tie(0),cout.tie(0);}
ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x),y/2);else return (x*f_p((x*x),y/2));}
int dx[9]= {1,-1,0,0,0,1,-1,1,-1};
int dy[9]= {0,0,1,-1,0,1,-1,-1,1};
const int MX=(1<<19);
struct SegmentTree{
    int tree[2*MX];
    int lazy[2*MX];
    void build(int cur ,int l,int r,vector<int> arr)
    {
        lazy[cur]=1e9;
        if(l==r)
        {
            tree[cur]=arr[l];
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        build(left,l,mid,arr);
        build(right,mid+1,r,arr);
        tree[cur]=min(tree[left],tree[right]);
    }
    void propagate(int i,int l,int r)
    {
        if(lazy[i]==1e9)return;
        tree[i]+=lazy[i];
        if(l!=r)
        {
            if(lazy[i*2]==1e9)lazy[i*2]=lazy[i];
            else lazy[i*2]+=lazy[i];
            if(lazy[i*2+1]==1e9)lazy[i*2+1]=lazy[i];
            else lazy[i*2+1]+=lazy[i];
        }
        lazy[i]=1e9;
    }
    void update(int cur,int l,int r,int a,int b,int val)
    {
        if(lazy[cur]!=1e9)
            propagate(cur,l,r);
        if(a>r||b<l)
            return;
        if(l>=a&&r<=b){
            lazy[cur]=val;
            propagate(cur,l,r);
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        update(left,l,mid,a,b,val);
        update(right,mid+1,r,a,b,val);
        tree[cur]=min(tree[left],tree[right]);
    }
    int getmin(int cur,int l,int r,int a,int b)
    {
        propagate(cur,l,r);
        if(a>r||b<l)return 1e9;
        if(l>=a&&r<=b)return tree[cur];
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        return min(getmin(left,l,mid,a,b),getmin(right,mid+1,r,a,b));
    }
}d;
int n,m;
vector<int> arr;
int main()
{
    //XsliferX();
    cin>>n;
    arr.resize(n+1);
    for(int i=0 ; i<n ; i++)scanf("%d",&arr[i]);
    d.build(1,0,n-1,arr);
    cin>>m;
    cin.ignore();
     string s;
    stringstream ss;
    vector<int> v(4);
    int counter=0;
    int x;
    for(int i=0;i<m;i++)
    {
       getline(cin,s);
        ss.clear();
        counter=0;
        ss<<s;
        while(ss>>x)
        {
            v[counter]=x;
            counter++;
        }
        if(counter==2)
        {
            int ans;
            if(v[0]<=v[1])
            ans=d.getmin(1,0,n-1,v[0],v[1]);
            else
            {
                ans=min(d.getmin(1,0,n-1,v[0],n-1),d.getmin(1,0,n-1,0,v[1]));
            }
            printf("%d\n",ans);
        }
        else
        {
            if(v[0]<=v[1])
            {
                d.update(1,0,n-1,v[0],v[1],v[2]);
            }
            else
            {
                d.update(1,0,n-1,v[0],n-1,v[2]);
                d.update(1,0,n-1,0,v[1],v[2]);
            }
        }
    }
    return 0;
}
/*a=97  A=65
z=122 Z=90
0=48
prime number of ones in their binary representation
*/
// for(int i=0 ; i<n ; i++)
//ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x)%MOD,y/2);else return (x*f_p((x*x)%MOD,y/2))%MOD;}
//freopen("output.txt","w",stdout);


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define F first
#define S second
#define pi 3.14159265359
#define EPS 1e-9
#define MOD 1000000007
void XsliferX(){ios::sync_with_stdio(0);ios_base::sync_with_stdio(0);cin.tie(0),cout.tie(0);}
ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x),y/2);else return (x*f_p((x*x),y/2));}
int dx[9]= {1,-1,0,0,0,1,-1,1,-1};
int dy[9]= {0,0,1,-1,0,1,-1,-1,1};
const int MX=(1<<19);
struct SegmentTree{
    ll tree[2*MX];
    int lazy[2*MX];
    void build(int cur ,int l,int r,vector<int> arr)
    {
        lazy[cur]=1e9;
        if(l==r)
        {
            tree[cur]=arr[l];
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        build(left,l,mid,arr);
        build(right,mid+1,r,arr);
        tree[cur]=min(tree[left],tree[right]);
    }
    void propagate(int i,int l,int r)
    {
        if(lazy[i]==1e9)return;
        tree[i]+=lazy[i];
        if(l!=r)
        {
            if(lazy[i*2]==1e9)lazy[i*2]=lazy[i];
            else lazy[i*2]+=lazy[i];
            if(lazy[i*2+1]==1e9)lazy[i*2+1]=lazy[i];
            else lazy[i*2+1]+=lazy[i];
        }
        lazy[i]=1e9;
    }
    void update(int cur,int l,int r,int a,int b,int val)
    {
        if(lazy[cur]!=1e9)
            propagate(cur,l,r);
        if(a>r||b<l)
            return;
        if(l>=a&&r<=b){
            lazy[cur]=val;
            propagate(cur,l,r);
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        update(left,l,mid,a,b,val);
        update(right,mid+1,r,a,b,val);
        tree[cur]=min(tree[left],tree[right]);
    }
    int getmin(int cur,int l,int r,int a,int b)
    {
        propagate(cur,l,r);
        if(a>r||b<l)return 1e9;
        if(l>=a&&r<=b)return tree[cur];
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        return min(getmin(left,l,mid,a,b),getmin(right,mid+1,r,a,b));
    }
}d;
int n,m;
vector<int> arr;
int main()
{
    //XsliferX();
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin>>n;
    arr.resize(n+1);
    for(int i=0 ; i<n ; i++)cin>>arr[i];
    d.build(1,0,n-1,arr);
    cin>>m;
    cin.ignore();
     string s;
    stringstream ss;
    vector<int> v(4);
    int counter=0;
    int x;
    for(int i=0;i<m;i++)
    {
       getline(cin,s);
        ss.clear();
        counter=0;
        ss<<s;
        while(ss>>x)
        {
            v[counter]=x;
            counter++;
        }
        if(counter==2)
        {
            if(v[0]<=v[1])
            cout << d.getmin(1,0,n-1,v[0],v[1])<< '\n';
            else
            {
                cout << min(d.getmin(1,0,n-1,v[0],n-1),d.getmin(1,0,n-1,0,v[1]))<< '\n';
            }
        }
        else
        {
            if(v[0]<=v[1])
            {
                d.update(1,0,n-1,v[0],v[1],v[2]);
            }
            else
            {
                d.update(1,0,n-1,v[0],n-1,v[2]);
                d.update(1,0,n-1,0,v[1],v[2]);
            }
        }
    }
    return 0;
}
/*a=97  A=65
z=122 Z=90
0=48
prime number of ones in their binary representation
*/
// for(int i=0 ; i<n ; i++)
//ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x)%MOD,y/2);else return (x*f_p((x*x)%MOD,y/2))%MOD;}
//freopen("output.txt","w",stdout);


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define F first
#define S second
#define pi 3.14159265359
#define EPS 1e-9
#define MOD 1000000007
void XsliferX(){ios::sync_with_stdio(0);ios_base::sync_with_stdio(0);cin.tie(0),cout.tie(0);}
ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x),y/2);else return (x*f_p((x*x),y/2));}
int dx[9]= {1,-1,0,0,0,1,-1,1,-1};
int dy[9]= {0,0,1,-1,0,1,-1,-1,1};
const int MX=(1<<19);
struct SegmentTree{
    ll tree[2*MX];
    ll lazy[2*MX];
    void build(int cur ,int l,int r,int arr[])
    {
        if(l==r)
        {
            tree[cur]=arr[l];
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        build(left,l,mid,arr);
        build(right,mid+1,r,arr);
        tree[cur]=min(tree[left],tree[right]);
    }
    void propagate(int i,int l,int r)
    {
        if(lazy[i]==0)return;
        tree[i]+=lazy[i];
        if(l!=r)
        {
            lazy[i*2]+=lazy[i];
            lazy[i*2+1]+=lazy[i];
        }
        lazy[i]=0;
    }
    void update(int cur,int l,int r,int a,int b,int val)
    {
        propagate(cur,l,r);
        if(a>r||b<l)
            return;
        if(l>=a&&r<=b){
            lazy[cur]=val;
            propagate(cur,l,r);
            return;
        }
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        update(left,l,mid,a,b,val);
        update(right,mid+1,r,a,b,val);
        tree[cur]=min(tree[left],tree[right]);
    }
    ll getmin(int cur,int l,int r,int a,int b)
    {
        propagate(cur,l,r);
        if(a>r||b<l)return 1e9;
        if(l>=a&&r<=b)return tree[cur];
        int left=2*cur;
        int right=2*cur+1;
        int mid=(l+r)/2;
        return min(getmin(left,l,mid,a,b),getmin(right,mid+1,r,a,b));
    }
}d;
int n,m;
int main()
{
    //XsliferX();
    cin>>n;
    int arr[n];
    for(int i=0 ; i<n ; i++)scanf("%d",&arr[i]);
    d.build(1,0,n-1,arr);
    cin>>m;
    cin.ignore();
     string s;
    stringstream ss;
    vector<int> v(4);
    int counter=0;
    int x;
    for(int i=0;i<m;i++)
    {
       getline(cin,s);
        ss.clear();
        counter=0;
        ss<<s;
        while(ss>>x)
        {
            v[counter]=x;
            counter++;
        }
        if(counter==2)
        {
            ll ans;
            if(v[0]<=v[1])
            ans=d.getmin(1,0,n-1,v[0],v[1]);
            else
            {
                ans=min(d.getmin(1,0,n-1,v[0],n-1),d.getmin(1,0,n-1,0,v[1]));
            }
            printf("%I64d\n",ans);
        }
        else
        {
            if(v[0]<=v[1])
            {
                d.update(1,0,n-1,v[0],v[1],v[2]);
            }
            else
            {
                d.update(1,0,n-1,v[0],n-1,v[2]);
                d.update(1,0,n-1,0,v[1],v[2]);
            }
        }
    }
    return 0;
}
/*a=97  A=65
z=122 Z=90
0=48
prime number of ones in their binary representation
*/
// for(int i=0 ; i<n ; i++)
//ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x)%MOD,y/2);else return (x*f_p((x*x)%MOD,y/2))%MOD;}
//freopen("output.txt","w",stdout);


/*#include "bits/stdc++.h"

using namespace std;

struct Segtree{

	int N;
	vector<int> ST, L;

	Segtree(vector<int> A){

		N = A.size();
		ST.resize(4*N);
		L.resize(4*N);

		build(1, 0, N-1, A);

	}

	void build(int node, int l, int r, vector<int> A){

		if(l == r){

			ST[node] = A[r];
			return;

		}

		build(2*node, l, (l+r)/2, A);
		build(2*node+1, ((l+r)/2)+1, r, A);

		ST[node] = min(ST[2*node], ST[2*node+1]);
		return;

	}

	int query(int i, int j){

		return query(1, 0, N-1, i, j);

	}

	int query(int node, int l, int r, int i, int j){

		if(L[node] != 0){

			ST[node] += L[node];

			if(l != r){

				L[2*node] += L[node];
				L[2*node+1] += L[node];

			}

			L[node] = 0;

		}

		if(i <= l && r <= j) return ST[node];

		if(j < l || r < i) return INT_MAX;

		return min(query(2*node, l, (l+r)/2, i, j), query(2*node+1, (l+r)/2+1, r, i, j));

	}

	void update(int i, int j, int x){
		uptade(1, 0, N-1, i, j, x);
	}

	void uptade(int node, int l, int r, int i, int j, int x){

		if(L[node] != 0){
			ST[node] += L[node];

			if(l != r){
				L[2*node] += L[node];
				L[2*node+1] += L[node];

			}

			L[node] = 0;

		}

		if(i <= l && r <= j){

			ST[node] += x;

			if(l != r){

				L[2*node] += x;
				L[2*node+1] += x;

			}

			return;

		}

		if(j < l || r < i) return;

		uptade(2*node, l, (l+r)/2, i, j, x);
		uptade(2*node+1, (l+r)/2+1, r, i, j, x);

		ST[node] = min(ST[2*node], ST[2*node+1]);

	}

};

int main(){

	int n, m;
	cin>>n;
	vector<int> A (n);

	for(int i = 0; i < n; i++){

		cin>>A[i];

	}

	Segtree ST(A);
	cin>>m;
	int lf, rg, v;
	for(int i = 0; i < m; i++){

		char d;

		cin>>lf>>rg;
		cin.get(d);

		if(d == ' '){

			cin>>v;

			if(lf > rg){

				ST.update(lf, A.size()-1, v);
				ST.update(0, rg, v);

			}else{

				ST.update(lf, rg, v);

			}

		}else{

			if(lf > rg){

				cout<<min(ST.query(lf, A.size()-1), ST.query(0, rg))<<endl;

			}else{

				cout<<ST.query(lf, rg)<<endl;

			}

		}

	}

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

struct SegmentTree {
	vector<int> ST, L;
	int N;

	SegmentTree(vector<int> &A) {
		N = A.size();

		ST.resize(4*N);
		L.resize(4*N, 0);
		build(1, 0, N-1, A);
	}

	void build(int node, int l, int r, vector<int> &A) {
		if(l == r) {
			ST[node] = A[r];
			return;
		}

		build(2*node, l, (l+r)/2, A);
		build(2*node+1, (l+r)/2+1, r, A);

		ST[node] = min(ST[2*node], ST[2*node+1]);
		return;
	}

	int query(int i, int j) {
		return query(1, 0, N-1, i, j);
	}

	int query(int node, int l, int r, int i, int j) {
		// Hay que actualizar
		if(L[node] != 0) {
			ST[node] += L[node];

			// Si no es hoja, pasar la marca
			if(l != r) {
				L[2*node] += L[node];
				L[2*node+1] += L[node];
			}

			L[node] = 0;
		}

		//Caso 1
		if(i <= l && r <= j) return ST[node];

		//Caso 2
		if(j < l || r < i) return INT_MAX; // INT_MAX ES INFINITO

		//Caso 3
		return min(query(2*node, l, (l+r)/2, i, j),
					query(2*node+1, (l+r)/2+1, r, i, j));
	}

	void update(int i, int j, int x) {
		update(1, 0, N-1, i, j, x);
	}

	void update(int node, int l, int r, int i, int j, int x) {
		// Hay que actualizar
		if(L[node] != 0) {
			ST[node] += L[node];

			// Si no es hoja, pasar la marca
			if(l != r) {
				L[2*node] += L[node];
				L[2*node+1] += L[node];
			}

			L[node] = 0;
		}

		// Caso 1
		if(i <= l && r <= j) {
			ST[node] += x;

			if(l != r) {
				L[2*node] += x;
				L[2*node+1] += x;
			}

			return;
		}

		// Caso 2
		if(j < l || r < i) return;

		// Caso 3
		update(2*node, l, (l+r)/2, i, j, x);
		update(2*node+1, (l+r)/2+1, r, i, j, x);

		ST[node] = min(ST[2*node], ST[2*node+1]);
	}
};

int main() {
	int n, m;
	cin>>n;
	vector<int> A (n);

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

	SegmentTree ST(A);

	cin>>m;
	int lf, rg, v;
	for(int i = 0; i < m; i++){

		char d;

		cin>>lf>>rg;
		cin.get(d);

		if(d == ' '){

			cin>>v;

			if(lf > rg){

				ST.update(lf, A.size()-1, v);
				ST.update(0, rg, v);

			}else{

				ST.update(lf, rg, v);

			}

		}else{

			if(lf > rg){

				cout<<min(ST.query(lf, A.size()-1), ST.query(0, rg))<<endl;

			}else{

				cout<<ST.query(lf, rg)<<endl;

			}

		}

	}
}


#include "bits/stdc++.h"

using namespace std;

struct Segtree{

	int N;
	vector<long long> ST, L;

	Segtree(vector<int> &A){

		N = A.size();
		ST.resize(4*N);
		L.resize(4*N);

		build(1, 0, N-1, A);

	}

	void build(int node, int l, int r, vector<int> &A){

		if(l == r){

			ST[node] = A[r];
			return;

		}

		build(2*node, l, (l+r)/2, A);
		build(2*node+1, ((l+r)/2)+1, r, A);

		ST[node] = min(ST[2*node], ST[2*node+1]);
		return;

	}

	int query(int i, int j){

		return query(1, 0, N-1, i, j);

	}

	int query(int node, int l, int r, int &i, int &j){

		if(L[node] != 0){

			ST[node] += L[node];

			if(l != r){

				L[2*node] += L[node];
				L[2*node+1] += L[node];

			}

			L[node] = 0;

		}

		if(i <= l && r <= j) return ST[node];

		if(j < l || r < i) return INT_MAX;

		return min(query(2*node, l, (l+r)/2, i, j),
					query(2*node+1, (l+r)/2+1, r, i, j));

	}

	void update(int i, int j, int x){
		uptade(1, 0, N-1, i, j, x);
	}

	void uptade(int node, int l, int r, int &i, int &j, int &x){

		if(L[node] != 0){
			ST[node] += L[node];

			if(l != r){
				L[2*node] += L[node];
				L[2*node+1] += L[node];

			}

			L[node] = 0;

		}

		if(i <= l && r <= j){

			ST[node] += x;

			if(l != r){

				L[2*node] += x;
				L[2*node+1] += x;

			}

			return;

		}

		if(j < l || r < i) return;

		uptade(2*node, l, (l+r)/2, i, j, x);
		uptade(2*node+1, (l+r)/2+1, r, i, j, x);

		ST[node] = min(ST[2*node], ST[2*node+1]);

	}

};

int main(){

	int n, m;
	cin>>n;
	vector<int> A (n);

	for(int i = 0; i < n; i++){

		cin>>A[i];

	}

	Segtree ST(A);
	cin>>m;
	int lf, rg, v;

	for(int i = 0; i < m; i++){

		char d;

		cin>>lf>>rg;
		cin.get(d);

		if(d == ' '){

			cin>>v;

			if(lf > rg){

				ST.update(lf, (A.size()-1), v);
				ST.update(0, rg, v);

			}else{

				ST.update(lf, rg, v);

			}

		}else{

			if(lf > rg){

				cout<<min(ST.query(lf, A.size()-1), ST.query(0, rg))<<endl;

			}else{

				cout<<ST.query(lf, rg)<<endl;

			}

		}

	}

}


#include "bits/stdc++.h"

using namespace std;

struct Segtree{

	int N;
	vector<long> ST, L;

	Segtree(vector<int> &A){

		N = A.size();
		ST.resize(4*N);
		L.resize(4*N);

		build(1, 0, N-1, A);

	}

	void build(int node, int l, int r, vector<int> &A){

		if(l == r){

			ST[node] = A[r];
			return;

		}

		build(2*node, l, (l+r)/2, A);
		build(2*node+1, ((l+r)/2)+1, r, A);

		ST[node] = min(ST[2*node], ST[2*node+1]);
		return;

	}

	int query(int i, int j){

		return query(1, 0, N-1, i, j);

	}

	int query(int node, int l, int r, int i, int j){

		if(L[node] != 0){

			ST[node] += L[node];

			if(l != r){

				L[2*node] += L[node];
				L[2*node+1] += L[node];

			}

			L[node] = 0;

		}

		if(i <= l && r <= j) return ST[node];

		if(j < l || r < i) return INT_MAX;

		return min(query(2*node, l, (l+r)/2, i, j),
					query(2*node+1, (l+r)/2+1, r, i, j));

	}

	void update(int i, int j, int x){
		uptade(1, 0, N-1, i, j, x);
	}

	void uptade(int node, int l, int r, int i, int j, int x){

		if(L[node] != 0){
			ST[node] += L[node];

			if(l != r){
				L[2*node] += L[node];
				L[2*node+1] += L[node];

			}

			L[node] = 0;

		}

		if(i <= l && r <= j){

			ST[node] += x;

			if(l != r){

				L[2*node] += x;
				L[2*node+1] += x;

			}

			return;

		}

		if(j < l || r < i) return;

		uptade(2*node, l, (l+r)/2, i, j, x);
		uptade(2*node+1, (l+r)/2+1, r, i, j, x);

		ST[node] = min(ST[2*node], ST[2*node+1]);

	}

};

int main(){

	int n, m;
	cin>>n;
	vector<int> A (n);

	for(int i = 0; i < n; i++){

		cin>>A[i];

	}

	Segtree ST(A);
	cin>>m;
	int lf, rg, v;
	for(int i = 0; i < m; i++){

		char d;

		cin>>lf>>rg;
		cin.get(d);

		if(d == ' '){

			cin>>v;

			if(lf > rg){

				ST.update(lf, A.size()-1, v);
				ST.update(0, rg, v);

			}else{

				ST.update(lf, rg, v);

			}

		}else{

			if(lf > rg){

				cout<<min(ST.query(lf, A.size()-1), ST.query(0, rg))<<endl;

			}else{

				cout<<ST.query(lf, rg)<<endl;

			}

		}

	}

}


#include "bits/stdc++.h"

using namespace std;

struct Segtree{

	int N;
	vector<long long> ST, L;

	Segtree(vector<int> &A){

		N = A.size();
		ST.resize(4*N);
		L.resize(4*N);

		build(1, 0, N-1, A);

	}

	void build(int node, int l, int r, vector<int> &A){

		if(l == r){

			ST[node] = A[r];
			return;

		}

		build(2*node, l, (l+r)/2, A);
		build(2*node+1, ((l+r)/2)+1, r, A);

		ST[node] = min(ST[2*node], ST[2*node+1]);
		return;

	}

	int query(int i, int j){

		return query(1, 0, N-1, i, j);

	}

	int query(int node, int l, int r, int i, int j){

		if(L[node] != 0){

			ST[node] += L[node];

			if(l != r){

				L[2*node] += L[node];
				L[2*node+1] += L[node];

			}

			L[node] = 0;

		}

		if(i <= l && r <= j) return ST[node];

		if(j < l || r < i) return INT_MAX;

		return min(query(2*node, l, (l+r)/2, i, j),
					query(2*node+1, (l+r)/2+1, r, i, j));

	}

	void update(int i, int j, int x){
		uptade(1, 0, N-1, i, j, x);
	}

	void uptade(int node, int l, int r, int i, int j, int x){

		if(L[node] != 0){
			ST[node] += L[node];

			if(l != r){
				L[2*node] += L[node];
				L[2*node+1] += L[node];

			}

			L[node] = 0;

		}

		if(i <= l && r <= j){

			ST[node] += x;

			if(l != r){

				L[2*node] += x;
				L[2*node+1] += x;

			}

			return;

		}

		if(j < l || r < i) return;

		uptade(2*node, l, (l+r)/2, i, j, x);
		uptade(2*node+1, (l+r)/2+1, r, i, j, x);

		ST[node] = min(ST[2*node], ST[2*node+1]);

	}

};

int main(){

	int n, m;
	cin>>n;
	vector<int> A (n);

	for(int i = 0; i < n; i++){

		cin>>A[i];

	}

	Segtree ST(A);
	cin>>m;
	int lf, rg, v;
	for(int i = 0; i < m; i++){

		char d;

		cin>>lf>>rg;
		cin.get(d);

		if(d == ' '){

			cin>>v;

			if(lf > rg){

				ST.update(lf, A.size()-1, v);
				ST.update(0, rg, v);

			}else{

				ST.update(lf, rg, v);

			}

		}else{

			if(lf > rg){

				cout<<min(ST.query(lf, A.size()-1), ST.query(0, rg))<<endl;

			}else{

				cout<<ST.query(lf, rg)<<endl;

			}

		}

	}

}


#include "bits/stdc++.h"

using namespace std;

struct Segtree{

	int N;
	vector<long long> ST, L;

	Segtree(vector<int> &A){

		N = A.size();
		ST.resize(4*N);
		L.resize(4*N);

		build(1, 0, N-1, A);

	}

	void build(long long node, long long l, long long r, vector<int> &A){

		if(l == r){

			ST[node] = A[r];
			return;

		}

		build(2*node, l, (l+r)/2, A);
		build(2*node+1, ((l+r)/2)+1, r, A);

		ST[node] = min(ST[2*node], ST[2*node+1]);
		return;

	}

	long long query(long long i, long long j){

		return query(1, 0, N-1, i, j);

	}

	long long query(long long node, long long l, long long r, long long &i, long long &j){

		if(L[node] != 0){

			ST[node] += L[node];

			if(l != r){

				L[2*node] += L[node];
				L[2*node+1] += L[node];

			}

			L[node] = 0;

		}

		if(i <= l && r <= j) return ST[node];

		if(j < l || r < i) return INT_MAX;

		return min(query(2*node, l, (l+r)/2, i, j),
					query(2*node+1, (l+r)/2+1, r, i, j));

	}

	void update(long long i, long long j, long long x){
		uptade(1, 0, N-1, i, j, x);
	}

	void uptade(long long node, long long l, long long r, long long &i, long long &j, long long &x){

		if(L[node] != 0){
			ST[node] += L[node];

			if(l != r){
				L[2*node] += L[node];
				L[2*node+1] += L[node];

			}

			L[node] = 0;

		}

		if(i <= l && r <= j){

			ST[node] += x;

			if(l != r){

				L[2*node] += x;
				L[2*node+1] += x;

			}

			return;

		}

		if(j < l || r < i) return;

		uptade(2*node, l, (l+r)/2, i, j, x);
		uptade(2*node+1, (l+r)/2+1, r, i, j, x);

		ST[node] = min(ST[2*node], ST[2*node+1]);

	}

};

int main(){

	int n, m;
	cin>>n;
	vector<int> A (n);

	for(int i = 0; i < n; i++){

		cin>>A[i];

	}

	Segtree ST(A);
	cin>>m;
	int lf, rg, v;

	for(int i = 0; i < m; i++){

		char d;

		cin>>lf>>rg;
		cin.get(d);

		if(d == ' '){

			cin>>v;

			if(lf > rg){

				ST.update(lf, (A.size()-1), v);
				ST.update(0, rg, v);

			}else{

				ST.update(lf, rg, v);

			}

		}else{

			if(lf > rg){

				cout<<min(ST.query(lf, A.size()-1), ST.query(0, rg))<<endl;

			}else{

				cout<<ST.query(lf, rg)<<endl;

			}

		}

	}

}


#include "bits/stdc++.h"

using namespace std;

struct Segtree{

	int N;
	vector<int> ST, L;

	Segtree(vector<int> &A){

		N = A.size();
		ST.resize(4*N);
		L.resize(4*N);

		build(1, 0, N-1, A);

	}

	void build(int node, int l, int r, vector<int> &A){

		if(l == r){

			ST[node] = A[r];
			return;

		}

		build(2*node, l, (l+r)/2, A);
		build(2*node+1, ((l+r)/2)+1, r, A);

		ST[node] = min(ST[2*node], ST[2*node+1]);
		return;

	}

	int query(int i, int j){

		return query(1, 0, N-1, i, j);

	}

	int query(int node, int l, int r, int i, int j){

		if(L[node] != 0){

			ST[node] += L[node];

			if(l != r){

				L[2*node] += L[node];
				L[2*node+1] += L[node];

			}

			L[node] = 0;

		}

		if(i <= l && r <= j) return ST[node];

		if(j < l || r < i) return INT_MAX;

		return min(query(2*node, l, (l+r)/2, i, j),
					query(2*node+1, (l+r)/2+1, r, i, j));

	}

	void update(int i, int j, int x){
		uptade(1, 0, N-1, i, j, x);
	}

	void uptade(int node, int l, int r, int i, int j, int x){

		if(L[node] != 0){
			ST[node] += L[node];

			if(l != r){
				L[2*node] += L[node];
				L[2*node+1] += L[node];

			}

			L[node] = 0;

		}

		if(i <= l && r <= j){

			ST[node] += x;

			if(l != r){

				L[2*node] += x;
				L[2*node+1] += x;

			}

			return;

		}

		if(j < l || r < i) return;

		uptade(2*node, l, (l+r)/2, i, j, x);
		uptade(2*node+1, (l+r)/2+1, r, i, j, x);

		ST[node] = min(ST[2*node], ST[2*node+1]);

	}

};

int main(){

	int n, m;
	cin>>n;
	vector<int> A (n);

	for(int i = 0; i < n; i++){

		cin>>A[i];

	}

	Segtree ST(A);
	cin>>m;
	int lf, rg, v;
	for(int i = 0; i < m; i++){

		char d;

		cin>>lf>>rg;
		cin.get(d);

		if(d == ' '){

			cin>>v;

			if(lf > rg){

				ST.update(lf, A.size()-1, v);
				ST.update(0, rg, v);

			}else{

				ST.update(lf, rg, v);

			}

		}else{

			if(lf > rg){

				cout<<min(ST.query(lf, A.size()-1), ST.query(0, rg))<<endl;

			}else{

				cout<<ST.query(lf, rg)<<endl;

			}

		}

	}

}


#include "bits/stdc++.h"

using namespace std;

struct SegTree{

	int N;
	vector<int> ST;

	SegTree(vector <int> A){

		N = A.size();
		ST.resize(N);

		build(1, 0, N-1, A);

	}

	void build(int node, int l, int r, vector<int> A){

		if(l == r){

			ST[node] = A[r];
			return;

		}

		build(2*node, l, (l+r)/2, A);
		build(2*node+1, ((l+r)/2)+1, r, A);

		ST[node] = min(ST[2*node], ST[2*node+1]);
		return;

	}

	int query(int i, int j){

		return query(1, 0, N-1, i, j);

	}

	int query(int node, int l, int r, int i, int j){

		if(i <= l && j <= r) return ST[node];

		if(i < l || j < r ) return INT_MAX;

		return min(query(2*node, l, (l+r)/2, i, j), query(2*node+1, (l+r)/2+1, r, i, j));

		return 0;

	}

};

int main(){

	int n, m;
	cin>>n;
	vector<int> A;
	A.resize(n);

	for(int i = 0; i < n; i++){

	}

	for(int i = 0; i < n; i++){

		cin>>A[i];

	}

	SegTree ST(A);

}


#include "bits/stdc++.h"

using namespace std;

struct Segtree{

	int N;
	vector<int> ST, L;

	Segtree(vector<int> A){

		N = A.size();
		ST.resize(4*N);
		L.resize(4*N);

		build(1, 0, N-1, A);

	}

	void build(int node, int l, int r, vector<int> A){

		if(l == r){

			ST[node] = A[r];
			return;

		}

		build(2*node, l, (l+r)/2, A);
		build(2*node+1, ((l+r)/2)+1, r, A);

		ST[node] = min(ST[2*node], ST[2*node+1]);
		return;

	}

	int query(int i, int j){

		return query(1, 0, N-1, i, j);

	}

	int query(int node, int l, int r, int i, int j){

		if(L[node] != 0){

			ST[node] += L[node];

			if(l != r){

				L[2*node] += L[node];
				L[2*node+1] += L[node];

			}

			L[node] = 0;

		}

		if(i <= l && r <= j) return ST[node];

		if(j < l || r < i) return INT_MAX;

		return min(query(2*node, l, (l+r)/2, i, j), query(2*node+1, (l+r)/2+1, r, i, j));

	}

	void update(int i, int j, int x){
		uptade(1, 0, N-1, i, j, x);
	}

	void uptade(int node, int l, int r, int i, int j, int x){

		if(L[node] != 0){
			ST[node] += L[node];

			if(l != r){
				L[2*node] += L[node];
				L[2*node+1] += L[node];

			}

			L[node] = 0;

		}

		if(i <= l && r <= j){

			ST[node] += x;

			if(l != r){

				L[2*node] += x;
				L[2*node+1] += x;

			}

			return;

		}

		if(j < l || r < i) return;

		uptade(2*node, l, (l+r)/2, i, j, x);
		uptade(2*node+1, (l+r)/2+1, r, i, j, x);

		ST[node] = min(ST[2*node], ST[2*node+1]);

	}

};

int main(){

	int n, m;
	cin>>n;
	vector<int> A (n);

	for(int i = 0; i < n; i++){

		cin>>A[i];

	}

	Segtree ST(A);
	cin>>m;
	int lf, rg, v;
	for(int i = 0; i < m; i++){

		char d;

		cin>>lf>>rg;
		cin.get(d);

		if(d == ' '){

			cin>>v;

			if(lf > rg){

				ST.update(lf, A.size()-1, v);
				ST.update(0, rg, v);

			}else{

				ST.update(lf, rg, v);

			}

		}else{

			if(lf > rg){

				cout<<min(ST.query(lf, A.size()-1), ST.query(0, rg))<<endl;

			}else{

				cout<<ST.query(lf, rg)<<endl;

			}

		}

	}

}


#include "bits/stdc++.h"

using namespace std;

const int inf = 10e9;

struct Segtree{

	int N;
	vector<long long> ST, L;

	Segtree(vector<int> &A){

		N = A.size();
		ST.resize(4*N);
		L.resize(4*N);

		build(1, 0, N-1, A);

	}

	void build(int node, int l, int r, vector<int> &A){

		if(l == r){

			ST[node] = A[r];
			return;

		}

		build(2*node, l, (l+r)/2, A);
		build(2*node+1, ((l+r)/2)+1, r, A);

		ST[node] = min(ST[2*node], ST[2*node+1]);
		return;

	}

	int query(int i, int j){

		return query(1, 0, N-1, i, j);

	}

	int query(int node, int l, int r, int i, int j){

		if(L[node] != 0){

			ST[node] += L[node];

			if(l != r){

				L[2*node] += L[node];
				L[2*node+1] += L[node];

			}

			L[node] = 0;

		}

		if(i <= l && r <= j) return ST[node];

		if(j < l || r < i) return inf;

		return min(query(2*node, l, (l+r)/2, i, j),
					query(2*node+1, (l+r)/2+1, r, i, j));

	}

	void update(int i, int j, int x){
		uptade(1, 0, N-1, i, j, x);
	}

	void uptade(int node, int l, int r, int i, int j, int x){

		if(L[node] != 0){
			ST[node] += L[node];

			if(l != r){
				L[2*node] += L[node];
				L[2*node+1] += L[node];

			}

			L[node] = 0;

		}

		if(i <= l && r <= j){

			ST[node] += x;

			if(l != r){

				L[2*node] += x;
				L[2*node+1] += x;

			}

			return;

		}

		if(j < l || r < i) return;

		uptade(2*node, l, (l+r)/2, i, j, x);
		uptade(2*node+1, (l+r)/2+1, r, i, j, x);

		ST[node] = min(ST[2*node], ST[2*node+1]);

	}

};

int main(){

	int n, m;
	cin>>n;
	vector<int> A (n);

	for(int i = 0; i < n; i++){

		cin>>A[i];

	}

	Segtree ST(A);
	cin>>m;
	int lf, rg, v;
	for(int i = 0; i < m; i++){

		char d;

		cin>>lf>>rg;
		cin.get(d);

		if(d == ' '){

			cin>>v;

			if(lf > rg){

				ST.update(lf, A.size()-1, v);
				ST.update(0, rg, v);

			}else{

				ST.update(lf, rg, v);

			}

		}else{

			if(lf > rg){

				cout<<min(ST.query(lf, A.size()-1), ST.query(0, rg))<<endl;

			}else{

				cout<<ST.query(lf, rg)<<endl;

			}

		}

	}

}


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<memory>
#include<memory.h>
#define maxn 200007
using namespace std;
long long MIN[maxn << 2], ADD[maxn << 2];
long long A[maxn], n;

void pushUp(long long rt)
{
	MIN[rt] = min(MIN[rt << 1], MIN[rt << 1 | 1]);
}

void buildtree(long long l, long long r, long long rt)
{
	if (l == r)
	{
		MIN[rt] = A[l];
		return;
	}
	long long m = (l+r) >> 1;
	buildtree(l, m, rt << 1);
	buildtree(m + 1, r, rt << 1 | 1);
	pushUp(rt);
}
void pushdown(long long rt)
{
	if (ADD[rt])
	{
		ADD[rt << 1] += ADD[rt];
		ADD[rt << 1 | 1] += ADD[rt];
		MIN[rt << 1] += ADD[rt];
		MIN[rt << 1 | 1] += ADD[rt];
		ADD[rt] = 0;
	}
}
void updata(long long L, long long R, long long C, long long l, long long r, long long rt)
{
	if (L <= l&&r <= R)
	{
		MIN[rt] += C;
		ADD[rt] += C;
		return;
	}
	long long m = (l + r) >> 1;
	pushdown(rt);
	if (L <= m)updata(L, R, C, l, m, rt<<1);

	if (R >  m)	updata(L, R, C, m + 1, r, rt<<1|1);
	pushUp(rt);
}

long long query(long long L, long long R, long long l, long long r, long long rt)
{
	if (L <= l&&r <= R)
	{
		return MIN[rt];
	}
	long long m = (l + r) >> 1;
	pushdown(rt);
	long long ANS = 0xffffff;
	if (L <= m)ANS = min(ANS, query(L, R, l, m, rt << 1));
	if(R>m)ANS = min(ANS, query(L, R, m+1, r, rt << 1|1));
	return ANS;
}

int main()
{
	while (scanf("%lld", &n) == 1 && n)
	{
		memset(ADD, 0, sizeof(ADD));
		for (long long i = 1; i <= n; i++)
			scanf("%lld", &A[i]);
		buildtree(1, n, 1);
		long long m;
		scanf("%lld", &m);
		for (long long i = 0; i < m; i++)
		{
			long long a, b, c; char ch;
			scanf("%lld%lld", &a, &b);
			a++; b++;
			scanf("%c", &ch);
			if(ch==' ')
			{
				scanf("%lld", &c);
				if (a <= b)
					updata(a, b, c, 1, n, 1);
				else
				{
					updata(a, n, c, 1, n, 1);
					updata(1, b, c, 1, n, 1);
				}
			}
			else
			{
				if (a <= b)
					cout << query(a, b, 1, n, 1) << endl;
				else
				{
					cout << min(query(1, b, 1, n, 1),query(a, n, 1, n, 1)) << endl;
				}
			}
		}
	}

	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<memory>
#include<memory.h>
#define maxn 200007
using namespace std;
long long MIN[maxn << 2], ADD[maxn << 2];
long long A[maxn], n;

void pushUp(long long rt)
{
	MIN[rt] = min(MIN[rt << 1], MIN[rt << 1 | 1]);
}

void buildtree(long long l, long long r, long long rt)
{
	if (l == r)
	{
		MIN[rt] = A[l];
		return;
	}
	long long m = (l+r) >> 1;
	buildtree(l, m, rt << 1);
	buildtree(m + 1, r, rt << 1 | 1);
	pushUp(rt);
}
void pushdown(long long rt)
{
	if (ADD[rt])
	{
		ADD[rt << 1] += ADD[rt];
		ADD[rt << 1 | 1] += ADD[rt];
		MIN[rt << 1] += ADD[rt];
		MIN[rt << 1 | 1] += ADD[rt];
		ADD[rt] = 0;
	}
}
void updata(long long L, long long R, long long C, long long l, long long r, long long rt)
{
	if (L <= l&&r <= R)
	{
		MIN[rt] += C;
		ADD[rt] += C;
		return;
	}
	long long m = (l + r) >> 1;
	pushdown(rt);
	if (L <= m)updata(L, R, C, l, m, rt<<1);

	if (R >  m)	updata(L, R, C, m + 1, r, rt<<1|1);
	pushUp(rt);
}

long long query(long long L, long long R, long long l, long long r, long long rt)
{
	if (L == l&&r == R)
	{
		return MIN[rt];
	}
	long long m = (l + r) >> 1;
	pushdown(rt);
	long long ANS = 0x7ffffffffff;
	if (L <= m&&R <= m)ANS = min(ANS, query(L, R, l, m, rt << 1));
	else
		if (R>m&&L>m)ANS = min(ANS, query(L, R, m + 1, r, rt << 1 | 1));
		else
		{
			if (L <= m)ANS = min(ANS, query(L, R, l, m, rt << 1));

			if (R > m)ANS = min(ANS, query(L, R, m + 1, r, rt << 1 | 1));
		}
	return ANS;
}

int main()
{
	while (scanf("%lld", &n) == 1 && n)
	{
		memset(ADD, 0, sizeof(ADD));
		for (long long i = 1; i <= n; i++)
			scanf("%lld", &A[i]);
		buildtree(1, n, 1);
		long long m;
		scanf("%lld", &m);
		for (long long i = 0; i < m; i++)
		{
			long long a, b, c; char ch;
			scanf("%lld%lld", &a, &b);
			a++; b++;
			scanf("%c", &ch);
			if(ch==' ')
			{
				scanf("%lld", &c);
				if (a <= b)
					updata(a, b, c, 1, n, 1);
				else
				{
					updata(a, n, c, 1, n, 1);
					updata(1, b, c, 1, n, 1);
				}
			}
			else
			{
				if (a <= b)
					cout << query(a, b, 1, n, 1) << endl;
				else
				{
					cout << min(query(1, b, 1, n, 1),query(a, n, 1, n, 1)) << endl;
				}
			}
		}
	}

	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<memory>
#include<memory.h>
#define maxn 200007
using namespace std;
long long MIN[maxn << 2], ADD[maxn << 2];
long long A[maxn], n;

void pushUp(long long rt)
{
	MIN[rt] = min(MIN[rt << 1], MIN[rt << 1 | 1]);
}

void buildtree(long long l, long long r, long long rt)
{
	if (l == r)
	{
		MIN[rt] = A[l];
		return;
	}
	long long m = (l+r) >> 1;
	buildtree(l, m, rt << 1);
	buildtree(m + 1, r, rt << 1 | 1);
	pushUp(rt);
}
void pushdown(long long rt)
{
	if (ADD[rt])
	{
		ADD[rt << 1] += ADD[rt];
		ADD[rt << 1 | 1] += ADD[rt];
		MIN[rt << 1] += ADD[rt];
		MIN[rt << 1 | 1] += ADD[rt];
		ADD[rt] = 0;
	}
}
void updata(long long L, long long R, long long C, long long l, long long r, long long rt)
{
	if (L == l&&r == R)
	{
		MIN[rt] += C;
		ADD[rt] += C;
		return;
	}
	long long m = (l + r) >> 1;
	pushdown(rt);
	if(L<=m&&R<=m)updata(L, R, C, l, m, rt << 1);
	else
		if(L>m&&R>m)updata(L, R, C, m + 1, r, rt << 1 | 1);
		else
		{
			if (L <= m)updata(L, m, C, l, m, rt << 1);

			if (R > m)	updata(m+1, R, C, m + 1, r, rt << 1 | 1);
		}
	pushUp(rt);
}

long long query(long long L, long long R, long long l, long long r, long long rt)
{
	if (L == l&&r == R)
	{
		return MIN[rt];
	}
	long long m = (l + r) >> 1;
	//pushdown(rt);
	long long ANS = 0x7ffffffffff;
	if (L <= m&&R <= m)ANS = min(ANS, query(L, R, l, m, rt << 1));
	else
		if (R>m&&L>m)ANS = min(ANS, query(L, R, m + 1, r, rt << 1 | 1));
		else
		{
			if (L <= m)ANS = min(ANS, query(L, m, l, m, rt << 1));

			if (R > m)ANS = min(ANS, query(m+1, R, m + 1, r, rt << 1 | 1));
		}
	return ANS;
}

int main()
{
	while (scanf("%lld", &n) == 1 && n)
	{
		memset(ADD, 0, sizeof(ADD));
		for (long long i = 1; i <= n; i++)
			scanf("%lld", &A[i]);
		buildtree(1, n, 1);
		long long m;
		scanf("%lld", &m);
		for (long long i = 0; i < m; i++)
		{
			long long a, b, c; char ch;
			scanf("%lld%lld", &a, &b);
			a++; b++;
			scanf("%c", &ch);
			if(ch==' ')
			{
				scanf("%lld", &c);
				if (a <= b)
					updata(a, b, c, 1, n, 1);
				else
				{
					updata(a, n, c, 1, n, 1);
					updata(1, b, c, 1, n, 1);
				}
			}
			else
			{
				if (a <= b)
					cout << query(a, b, 1, n, 1) << endl;
				else
				{
					cout << min(query(1, b, 1, n, 1),query(a, n, 1, n, 1)) << endl;
				}
			}
		}
	}

	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<memory>
#include<memory.h>
#define maxn 200007
using namespace std;
int MIN[maxn << 2], ADD[maxn << 2];
int A[maxn], n;

void pushUp(int rt)
{
	MIN[rt] = min(MIN[rt << 1], MIN[rt << 1 | 1]);
}

void buildtree(int l, int r, int rt)
{
	if (l == r)
	{
		MIN[rt] = A[l];
		return;
	}
	int m = (l+r) >> 1;
	buildtree(l, m, rt << 1);
	buildtree(m + 1, r, rt << 1 | 1);
	pushUp(rt);
}
void pushdown(int rt)
{
	if (ADD[rt])
	{
		ADD[rt << 1] += ADD[rt];
		ADD[rt << 1 | 1] += ADD[rt];
		MIN[rt << 1] += ADD[rt];
		MIN[rt << 1 | 1] += ADD[rt];
		ADD[rt] = 0;
	}
}
void updata(int L, int R, int C, int l, int r, int rt)
{
	if (L <= l&&r <= R)
	{
		MIN[rt] += C;
		ADD[rt] += C;
		return;
	}
	int m = (l + r) >> 1;
	pushdown(rt);
	if (L <= m)updata(L, R, C, l, m, rt<<1);

	if (R >  m)	updata(L, R, C, m + 1, r, rt<<1|1);
	pushUp(rt);
}

int query(int L, int R, int l, int r, int rt)
{
	if (L <= l&&r <= R)
	{
		return MIN[rt];
	}
	int m = (l + r) >> 1;
	pushdown(rt);
	int ANS = 0xffffff;
	if (L <= m)ANS = min(ANS, query(L, R, l, m, rt << 1));
	if(R>m)ANS = min(ANS, query(L, R, m+1, r, rt << 1|1));
	return ANS;
}

int main()
{
	while (scanf("%d", &n) == 1 && n)
	{
		memset(ADD, 0, sizeof(ADD));
		for (int i = 1; i <= n; i++)
			scanf("%d", &A[i]);
		buildtree(1, n, 1);
		int m;
		scanf("%d", &m);
		for (int i = 0; i < m; i++)
		{
			int a, b, c; char ch;
			scanf("%d%d", &a, &b);
			a++; b++;
			scanf("%c", &ch);
			if(ch==' ')
			{
				scanf("%d", &c);
				if (a <= b)
					updata(a, b, c, 1, n, 1);
				else
				{
					updata(a, n, c, 1, n, 1);
					updata(1, b, c, 1, n, 1);
				}
			}
			else
			{
				if (a <= b)
					cout << query(a, b, 1, n, 1) << endl;
				else
				{
					cout << min(query(1, b, 1, n, 1),query(a, n, 1, n, 1)) << endl;
				}
			}
		}
	}

	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<memory>
#include<memory.h>
#define maxn 200007
using namespace std;
long long MIN[maxn << 2], ADD[maxn << 2];
long long A[maxn], n;

void pushUp(long long rt)
{
	MIN[rt] = min(MIN[rt << 1], MIN[rt << 1 | 1]);
}

void buildtree(long long l, long long r, long long rt)
{
	if (l == r)
	{
		MIN[rt] = A[l];
		return;
	}
	long long m = (l+r) >> 1;
	buildtree(l, m, rt << 1);
	buildtree(m + 1, r, rt << 1 | 1);
	pushUp(rt);
}
void pushdown(long long rt)
{
	if (ADD[rt])
	{
		ADD[rt << 1] += ADD[rt];
		ADD[rt << 1 | 1] += ADD[rt];
		MIN[rt << 1] += ADD[rt];
		MIN[rt << 1 | 1] += ADD[rt];
		ADD[rt] = 0;
	}
}
void updata(long long L, long long R, long long C, long long l, long long r, long long rt)
{
	if (L <= l&&r <= R)
	{
		MIN[rt] += C;
		ADD[rt] += C;
		return;
	}
	long long m = (l + r) >> 1;
	pushdown(rt);
	if (L <= m)updata(L, R, C, l, m, rt<<1);

	if (R >  m)	updata(L, R, C, m + 1, r, rt<<1|1);
	pushUp(rt);
}

long long query(long long L, long long R, long long l, long long r, long long rt)
{
	if (L <= l&&r <= R)
	{
		return MIN[rt];
	}
	long long m = (l + r) >> 1;
	pushdown(rt);
	long long ANS = 0x7ffffffffff;
	if (L <= m)ANS = min(ANS, query(L, R, l, m, rt << 1));
	if(R>m)ANS = min(ANS, query(L, R, m+1, r, rt << 1|1));
	return ANS;
}

int main()
{
	while (scanf("%lld", &n) == 1 && n)
	{
		memset(ADD, 0, sizeof(ADD));
		for (long long i = 1; i <= n; i++)
			scanf("%lld", &A[i]);
		buildtree(1, n, 1);
		long long m;
		scanf("%lld", &m);
		for (long long i = 0; i < m; i++)
		{
			long long a, b, c; char ch;
			scanf("%lld%lld", &a, &b);
			a++; b++;
			scanf("%c", &ch);
			if(ch==' ')
			{
				scanf("%lld", &c);
				if (a <= b)
					updata(a, b, c, 1, n, 1);
				else
				{
					updata(a, n, c, 1, n, 1);
					updata(1, b, c, 1, n, 1);
				}
			}
			else
			{
				if (a <= b)
					cout << query(a, b, 1, n, 1) << endl;
				else
				{
					cout << min(query(1, b, 1, n, 1),query(a, n, 1, n, 1)) << endl;
				}
			}
		}
	}

	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<memory>
#include<memory.h>
#define maxn 200007
using namespace std;
int MIN[maxn << 2], ADD[maxn << 2];
int A[maxn], n;

void pushUp(int rt)
{
	MIN[rt] = min(MIN[rt << 1], MIN[rt << 1 | 1]);
}

void buildtree(int l, int r, int rt)
{
	if (l == r)
	{
		MIN[rt] = A[l];
		return;
	}
	int m = (l+r) >> 1;
	buildtree(l, m, rt << 1);
	buildtree(m + 1, r, rt << 1 | 1);
	pushUp(rt);
}
void pushdown(int rt, int ln, int rn)
{
	if (ADD[rt])
	{
		ADD[rt << 1] += ADD[rt];
		ADD[rt << 1 | 1] += ADD[rt];
		MIN[rt << 1] += ADD[rt];
		MIN[rt << 1 | 1] += ADD[rt];
		ADD[rt] = 0;
	}
}
void updata(int L, int R, int C, int l, int r, int rt)
{
	if (L <= l&&r <= R)
	{
		MIN[rt] += C;
		ADD[rt] += C;
		return;
	}
	int m = (l + r) >> 1;
	pushdown(rt, m - l + 1, r - m);
	if (L <= m)updata(L, R, C, l, m, rt<<1);
	else
		updata(L, R, C, m + 1, r, rt<<1|1);
	pushUp(rt);
}

int query(int L, int R, int l, int r, int rt)
{
	if (L <= l&&r <= R)
	{
		return MIN[rt];
	}
	int m = (l + r) >> 1;
	pushdown(rt, m - l + 1, r - m);
	int ANS = 0xffffff;
	if (L <= m)ANS = min(ANS, query(L, R, l, m, rt << 1));
	if(R>m)ANS = min(ANS, query(L, R, m+1, r, rt << 1|1));
	return ANS;
}

int main()
{
	while (scanf("%d", &n) == 1 && n)
	{
		memset(ADD, 0, sizeof(ADD));
		for (int i = 1; i <= n; i++)
			scanf("%d", &A[i]);
		buildtree(1, n, 1);
		int m;
		scanf("%d", &m);
		for (int i = 0; i < m; i++)
		{
			int a, b, c; char ch;
			scanf("%d%d", &a, &b);
			a++; b++;
			scanf("%c", &ch);
			if(ch==' ')
			{
				scanf("%d", &c);
				if (a <= b)
					updata(a, b, c, 1, n, 1);
				else
				{
					updata(a, n, c, 1, n, 1);
					updata(1, b, c, 1, n, 1);
				}
			}
			else
			{
				if (a <= b)
					cout << query(a, b, 1, n, 1) << endl;
				else
				{
					cout << min(query(1, b, 1, n, 1),query(a, n, 1, n, 1)) << endl;
				}
			}
		}
	}

	return 0;
}