#include <bits/stdc++.h>
using namespace std;
function<void(void)> ____ = []() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
};
const int MOD = 1e9 + 7;
const int MAXN = 1e5 + 7;
struct Matrix {
  int mat[2][2];
  Matrix(int tag = 0) {
    mat[0][0] = mat[1][1] = tag;
    mat[0][1] = mat[1][0] = 0;
  }
  Matrix operator*(const Matrix &rhs) const {
    Matrix ret(0);
    for (int i = 0; i < 2; i++)
      for (int j = 0; j < 2; j++)
        for (int k = 0; k < 2; k++)
          ret.mat[i][j] =
              (ret.mat[i][j] + 1ll * mat[i][k] * rhs.mat[k][j]) % MOD;
    return ret;
  }
  Matrix operator+(const Matrix &rhs) const {
    Matrix ret(0);
    for (int i = 0; i < 2; i++)
      for (int j = 0; j < 2; j++)
        ret.mat[i][j] = (mat[i][j] + rhs.mat[i][j]) % MOD;
    return ret;
  }
  Matrix operator^(int b) {
    Matrix ret(1), A = *this;
    while (b) {
      if (b & 1) ret = ret * A;
      b >>= 1;
      A = A * A;
    }
    return ret;
  }
};
struct SegmentTree {
  pair<int, int> w[MAXN << 2];
  int l[MAXN << 2], r[MAXN << 2];
  Matrix mul[MAXN << 2];
  void pushup(int rt) {
    w[rt].first = (w[rt << 1].first + w[rt << 1 | 1].first) % MOD;
    w[rt].second = (w[rt << 1].second + w[rt << 1 | 1].second) % MOD;
  }
  void pushdown(int rt) {
    w[rt << 1] = make_pair((1ll * w[rt << 1].first * mul[rt].mat[0][0] +
                            1ll * w[rt << 1].second * mul[rt].mat[1][0]) %
                               MOD,
                           (1ll * w[rt << 1].first * mul[rt].mat[0][1] +
                            1ll * w[rt << 1].second * mul[rt].mat[1][1]) %
                               MOD);
    w[rt << 1 | 1] =
        make_pair((1ll * w[rt << 1 | 1].first * mul[rt].mat[0][0] +
                   1ll * w[rt << 1 | 1].second * mul[rt].mat[1][0]) %
                      MOD,
                  (1ll * w[rt << 1 | 1].first * mul[rt].mat[0][1] +
                   1ll * w[rt << 1 | 1].second * mul[rt].mat[1][1]) %
                      MOD);
    mul[rt << 1] = mul[rt << 1] * mul[rt];
    mul[rt << 1 | 1] = mul[rt << 1 | 1] * mul[rt];
    mul[rt] = Matrix(1);
  }
  void build(int L, int R, int rt = 1) {
    mul[rt] = Matrix(1);
    l[rt] = L;
    r[rt] = R;
    if (L + 1 == R) {
      w[rt] = make_pair(1, 0);
      return;
    }
    int mid = (L + R) >> 1;
    build(L, mid, rt << 1);
    build(mid, R, rt << 1 | 1);
    pushup(rt);
  }
  void update(int L, int R, Matrix A, int rt = 1) {
    if (L >= r[rt] or l[rt] >= R) return;
    if (L <= l[rt] and r[rt] <= R) {
      w[rt] = make_pair(
          (1ll * w[rt].first * A.mat[0][0] + 1ll * w[rt].second * A.mat[1][0]) %
              MOD,
          (1ll * w[rt].first * A.mat[0][1] + 1ll * w[rt].second * A.mat[1][1]) %
              MOD);
      mul[rt] = mul[rt] * A;
      return;
    }
    pushdown(rt);
    update(L, R, A, rt << 1);
    update(L, R, A, rt << 1 | 1);
    pushup(rt);
  }
  int query(int L, int R, int rt = 1) {
    if (L >= r[rt] or l[rt] >= R) return 0;
    if (L <= l[rt] and r[rt] <= R) return w[rt].first;
    pushdown(rt);
    return (0ll + query(L, R, rt << 1) + query(L, R, rt << 1 | 1)) % MOD;
  }
} ST;
int n, q;
void solve() {
  cin >> n >> q;
  ST.build(1, n + 1);
  Matrix M(0);
  M.mat[0][0] = M.mat[1][0] = M.mat[0][1] = 1;
  for (int i = 1; i <= n; i++) {
    int x;
    cin >> x;
    ST.update(i, i + 1, M ^ (x - 1));
  }
  while (q--) {
    int op, l, r;
    cin >> op >> l >> r;
    if (op == 1) {
      int x;
      cin >> x;
      ST.update(l, r + 1, M ^ x);
    } else
      cout << ST.query(l, r + 1) << endl;
  }
}
int main() {
  ____();
  solve();
  return 0;
}
