#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
const int MOD = 1e9 + 7;
int a[MAXN];
class Matrix {
 public:
  void prinf() {
    for (int i = 0; i < 2; i++) {
      for (int j = 0; j < 2; j++) {
        cout << a[i][j];
      }
      cout << endl;
    }
  }
  long long a[2][2];
  Matrix() { memset(a, 0, sizeof a); }
  void init() {
    for (int i = 0; i < 2; i++)
      for (int j = 0; j < 2; j++) a[i][j] = (i == j);
  }
  Matrix operator+(const Matrix &B) const {
    Matrix C;
    for (int i = 0; i < 2; i++)
      for (int j = 0; j < 2; j++) C.a[i][j] = (a[i][j] + B.a[i][j]) % MOD;
    return C;
  }
  Matrix operator*(const Matrix &B) const {
    Matrix C;
    for (int i = 0; i < 2; i++)
      for (int k = 0; k < 2; k++)
        for (int j = 0; j < 2; j++)
          C.a[i][j] = (C.a[i][j] + 1LL * a[i][k] * B.a[k][j]) % MOD;
    return C;
  }
  Matrix operator^(const int &t) const {
    Matrix A = (*this), res;
    res.init();
    int p = t;
    while (p) {
      if (p & 1) res = res * A;
      A = A * A;
      p >>= 1;
    }
    return res;
  }
};
Matrix sum[MAXN << 2], add[MAXN << 2], f;
void pushdown(int rt) {
  sum[rt << 1] = sum[rt << 1] * add[rt];
  sum[rt << 1 | 1] = sum[rt << 1 | 1] * add[rt];
  add[rt << 1] = add[rt << 1] * add[rt];
  add[rt << 1 | 1] = add[rt << 1 | 1] * add[rt];
  add[rt].init();
}
void pushup(int rt) { sum[rt] = sum[rt << 1] + sum[rt << 1 | 1]; }
void build(int l, int r, int rt) {
  sum[rt].init();
  add[rt].init();
  if (l == r) {
    sum[rt] = f ^ (a[l] - 1);
    return;
  }
  int m = (l + r) >> 1;
  build(l, m, rt << 1);
  build(m + 1, r, rt << 1 | 1);
  pushup(rt);
}
void update(int L, int R, Matrix v, int l, int r, int rt) {
  if (L <= l && R >= r) {
    sum[rt] = sum[rt] * v;
    add[rt] = add[rt] * v;
    return;
  }
  pushdown(rt);
  int m = (l + r) >> 1;
  if (L <= m) update(L, R, v, l, m, rt << 1);
  if (R > m) update(L, R, v, m + 1, r, rt << 1 | 1);
  pushup(rt);
}
long long query(int L, int R, int l, int r, int rt) {
  if (L <= l && R >= r) {
    return sum[rt].a[0][0];
  }
  pushdown(rt);
  int m = (l + r) >> 1;
  int cnt = 0;
  if (L <= m) cnt = (cnt + query(L, R, l, m, rt << 1)) % MOD;
  if (R > m) cnt = (cnt + query(L, R, m + 1, r, rt << 1 | 1)) % MOD;
  return cnt;
}
int main() {
  int m, n;
  f.a[0][0] = 1;
  f.a[0][1] = 1;
  f.a[1][0] = 1;
  f.a[1][1] = 0;
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
  build(1, n, 1);
  int a1, b, c;
  for (int i = 0; i < m; i++) {
    scanf("%d %d %d", &a1, &b, &c);
    if (a1 == 1) {
      int s;
      scanf("%d", &s);
      update(b, c, f ^ s, 1, n, 1);
    } else {
      cout << query(b, c, 1, n, 1) % MOD << endl;
    }
  }
}
