#include <bits/stdc++.h>
using namespace std;
template <class T>
class TSegmentTree {
 public:
  virtual T combine(const T& a, const T& b) = 0;
  virtual T neutral() = 0;
  virtual void push_value(T& dst, const T& src, int len) {}
  vector<T> t;
  int n;
  T neutral_;
  void init(int n_) {
    n = n_;
    t.resize(4 * n);
    neutral_ = neutral();
  }
  void build(const vector<T>& a) { build(a, 1, 0, n - 1); }
  T query(int l, int r) {
    assert(0 <= l && l < n);
    assert(0 <= r && r < n);
    return get(1, 0, n - 1, l, r);
  }
  void update(int l, int r, const T& val) {
    assert(0 <= l && l < n);
    assert(0 <= r && r < n);
    update(1, 0, n - 1, l, r, val);
  }
  void dump() { dump(1, 0, n - 1); }
  void dump(int v, int tl, int tr) {
    printf("[%d, %d] -> ", tl, tr);
    t[v].show();
    if (tl == tr) return;
    int tm = (tl + tr) / 2;
    dump(v * 2, tl, tm);
    dump(v * 2 + 1, tm + 1, tr);
  }

 private:
  void build(const vector<T>& a, int v, int tl, int tr) {
    if (tl == tr) {
      t[v] = a[tl];
    } else {
      int tm = (tl + tr) / 2;
      build(a, v * 2, tl, tm);
      build(a, v * 2 + 1, tm + 1, tr);
      t[v] = combine(t[v * 2], t[v * 2 + 1]);
    }
  }
  T get(int v, int tl, int tr, int l, int r) {
    if (l > r) {
      return neutral_;
    }
    if (l == tl && r == tr) {
      return t[v];
    }
    int tm = (tl + tr) / 2;
    push_value(t[v * 2], t[v], tm - tl + 1);
    push_value(t[v * 2 + 1], t[v], tr - tm);
    T left = get(v * 2, tl, tm, l, min(r, tm));
    T right = get(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r);
    t[v] = combine(t[v * 2 + 1], t[v * 2]);
    return combine(left, right);
  }
  void update(int v, int tl, int tr, int l, int r, const T& val) {
    if (l > r) {
      return;
    }
    if (l == tl && tr == r) {
      push_value(t[v], val, tr - tl + 1);
      return;
    }
    int tm = (tl + tr) / 2;
    push_value(t[v * 2], t[v], tm - tl + 1);
    push_value(t[v * 2 + 1], t[v], tr - tm);
    update(v * 2, tl, tm, l, min(r, tm), val);
    update(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r, val);
    t[v] = combine(t[v * 2], t[v * 2 + 1]);
  }
};
struct TNode {
  long long value;
  long long add;
  TNode(long long value_, long long add_) : value(value_), add(add_) {}
  TNode() : value(0), add(0) {}
};
const long long INF = 1e18;
class TMyTree : public TSegmentTree<TNode> {
  TNode neutral() { return TNode(INF, 0); }
  TNode combine(const TNode& a, const TNode& b) {
    TNode node;
    node.add = 0;
    node.value = min(a.value, b.value);
    return node;
  }
  void push_value(TNode& dst, const TNode& src, int len) {
    dst.add += src.add;
    dst.value += src.add;
  }
};
char buf[100];
int main() {
  int n;
  cin >> n;
  vector<TNode> a;
  for (int i = 0; i < n; ++i) {
    int x;
    scanf("%d", &x);
    a.push_back(TNode(x, 0));
  }
  TMyTree tree;
  tree.init(n);
  tree.build(a);
  int m;
  scanf("%d\n", &m);
  for (int i = 0; i < m; ++i) {
    gets(buf);
    int x, y, v;
    if (sscanf(buf, "%d%d%d", &x, &y, &v) == 3) {
      TNode val(0, v);
      if (x > y) {
        tree.update(x, n - 1, val);
        tree.update(0, y, val);
      } else {
        tree.update(x, y, val);
      }
    } else {
      long long res;
      if (x > y) {
        TNode v1 = tree.query(x, n - 1);
        TNode v2 = tree.query(0, y);
        res = min(v1.value, v2.value);
      } else {
        TNode v = tree.query(x, y);
        res = v.value;
      }
      cout << res << endl;
    }
  }
  return 0;
}
