#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
const int mod = 1e9 + 7;
struct matrix {
  long long m[6][6];
  void init() {
    m[0][0] = m[1][1] = 1;
    m[1][0] = m[0][1] = 0;
  }
};
matrix data[maxn << 2], lazy[maxn << 2];
matrix operator*(matrix a, matrix b) {
  matrix t;
  memset(t.m, 0, sizeof(t.m));
  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 2; j++) {
      for (int k = 0; k < 2; k++) {
        t.m[i][j] = (t.m[i][j] + a.m[i][k] * b.m[k][j]) % mod;
      }
    }
  }
  return t;
}
matrix pow_mul(long long m) {
  matrix res, aa;
  res.init();
  aa.m[0][0] = aa.m[0][1] = aa.m[1][0] = 1;
  aa.m[1][1] = 0;
  while (m) {
    if (m & 1) res = res * aa;
    aa = aa * aa;
    m >>= 1;
  }
  return res;
}
matrix operator+(matrix a, matrix b) {
  matrix c;
  memset(c.m, 0, sizeof(c.m));
  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 2; j++) {
      c.m[i][j] = (a.m[i][j] + b.m[i][j]) % mod;
    }
  }
  return c;
}
void pushup(int x) { data[x] = data[x * 2] + data[x * 2 + 1]; }
void Creat(int l, int r, int k) {
  lazy[k].init();
  data[k].init();
  if (l == r) {
    long long f;
    cin >> f;
    data[k] = pow_mul(f - 1);
    return;
  }
  int mid = (l + r) >> 1;
  Creat(l, mid, k * 2);
  Creat(mid + 1, r, k * 2 + 1);
  pushup(k);
}
void pushdown(int k) {
  data[k * 2] = data[k * 2] * lazy[k];
  data[k * 2 + 1] = data[k * 2 + 1] * lazy[k];
  lazy[k * 2] = lazy[k * 2] * lazy[k];
  lazy[k * 2 + 1] = lazy[k * 2 + 1] * lazy[k];
  lazy[k].init();
}
void updata(int l, int r, int L, int R, int k, matrix v) {
  if (l <= L && r >= R) {
    data[k] = data[k] * v;
    lazy[k] = lazy[k] * v;
    return;
  }
  pushdown(k);
  int mid = (L + R) / 2;
  if (l <= mid) updata(l, r, L, mid, k * 2, v);
  if (r >= mid + 1) updata(l, r, mid + 1, R, k * 2 + 1, v);
  pushup(k);
}
long long query(int l, int r, int L, int R, int k) {
  if (L >= l && R <= r) return data[k].m[0][0];
  pushdown(k);
  int mid = (L + R) / 2;
  long long ans = 0;
  if (l <= mid) ans = (ans + query(l, r, L, mid, k * 2)) % mod;
  if (r >= mid + 1) ans = (ans + query(l, r, mid + 1, R, k * 2 + 1)) % mod;
  return ans;
}
void middleshow(int l, int r, int x) {
  if (l == r) {
    cout << data[x].m[0][0] << endl;
    return;
  }
  int mid = (l + r) / 2;
  middleshow(l, mid, x * 2);
  middleshow(mid + 1, r, x * 2 + 1);
}
int main() {
  int n, m;
  cin >> n >> m;
  Creat(1, n, 1);
  while (m--) {
    int flag;
    int l, r;
    cin >> flag >> l >> r;
    if (flag == 1) {
      long long v;
      cin >> v;
      matrix t = pow_mul(v);
      updata(l, r, 1, n, 1, t);
    } else {
      cout << query(l, r, 1, n, 1) << endl;
    }
  }
  return 0;
}
