#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
const int maxt = 1 << 20;
const long long mov[2][2] = {{1, 1}, {1, 0}};
long long val[maxt], nval[maxt];
long long tag[maxt][2][2];
int n, m;
long long A[maxn];
inline void Mul(long long a[2][2], long long b[2][2]) {
  long long c[2][2] = {{0, 0}, {0, 0}};
  for (int i = 0; i < 2; i++)
    for (int j = 0; j < 2; j++)
      for (int k = 0; k < 2; k++)
        (c[i][j] += (a[i][k] * b[k][j] % 1000000007)) %= 1000000007;
  for (int i = 0; i < 2; i++)
    for (int j = 0; j < 2; j++) b[i][j] = c[i][j];
}
inline void quickpow(long long ans[2][2], long long ind) {
  ans[0][0] = 1;
  ans[0][1] = 0;
  ans[1][0] = 0;
  ans[1][1] = 1;
  long long base[2][2];
  for (int i = 0; i < 2; i++)
    for (int j = 0; j < 2; j++) base[i][j] = mov[i][j];
  while (ind > 0) {
    if (ind & 1LL) Mul(base, ans);
    ind >>= 1LL;
    Mul(base, base);
  }
}
inline void upd(int x) {
  val[x] = (val[x * 2] + val[x * 2 + 1]) % 1000000007;
  nval[x] = (nval[x * 2] + nval[x * 2 + 1]) % 1000000007;
}
inline void retag(int x, long long tmp[2][2]) {
  long long buf = val[x];
  val[x] = (nval[x] * tmp[1][0] + val[x] * tmp[1][1]) % 1000000007;
  nval[x] = (nval[x] * tmp[0][0] + buf * tmp[0][1]) % 1000000007;
}
inline void pushdown(int x, int l, int r) {
  if (l != r) {
    retag(x * 2, tag[x]);
    retag(x * 2 + 1, tag[x]);
    Mul(tag[x], tag[x * 2]);
    Mul(tag[x], tag[x * 2 + 1]);
    upd(x);
  }
  tag[x][0][0] = tag[x][1][1] = 1;
  tag[x][0][1] = tag[x][1][0] = 0;
}
inline void Add(int x, int l, int r, int tl, int tr, long long tmp[2][2]) {
  if (l > tr || r < tl) return;
  if (tl <= l && r <= tr) {
    retag(x, tmp);
    Mul(tmp, tag[x]);
    return;
  }
  pushdown(x, l, r);
  int mid = (l + r) >> 1;
  Add(x * 2, l, mid, tl, tr, tmp);
  Add(x * 2 + 1, mid + 1, r, tl, tr, tmp);
  upd(x);
}
long long res;
inline void Sum(int x, int l, int r, int tl, int tr) {
  if (l > tr || r < tl) return;
  pushdown(x, l, r);
  if (tl <= l && r <= tr) {
    res += val[x];
    if (res >= 1000000007) res -= 1000000007;
    return;
  }
  int mid = (l + r) >> 1;
  Sum(x * 2, l, mid, tl, tr);
  Sum(x * 2 + 1, mid + 1, r, tl, tr);
}
inline void build(int x, int l, int r) {
  if (l == r) {
    long long tmp[2][2];
    quickpow(tmp, A[l] - 1);
    val[x] = (tmp[1][0] + tmp[1][1]) % 1000000007;
    nval[x] = (tmp[0][0] + tmp[0][1]) % 1000000007;
    return;
  }
  int mid = (l + r) >> 1;
  build(x * 2, l, mid);
  build(x * 2 + 1, mid + 1, r);
  upd(x);
}
int main() {
  for (int i = 0; i < maxt; i++)
    tag[i][0][0] = tag[i][1][1] = 1, tag[i][0][1] = tag[i][1][0] = 0;
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; i++) scanf("%I64d", &A[i]);
  build(1, 0, n - 1);
  while (m--) {
    int tp, l, r;
    scanf("%d%d%d", &tp, &l, &r);
    l--, r--;
    if (tp == 1) {
      long long x;
      scanf("%I64d", &x);
      long long tmp[2][2];
      quickpow(tmp, x);
      Add(1, 0, n - 1, l, r, tmp);
    } else {
      res = 0;
      Sum(1, 0, n - 1, l, r);
      printf("%I64d\n", res);
    }
  }
  return 0;
}
