#include <bits/stdc++.h>
using namespace std;
const int maxn = 2;
const int mod = 1000000007;
int num = 2;
struct mat {
  long long data[maxn][maxn];
  bool noone() {
    if (data[0][0] != 1 || data[1][1] != 1 || data[0][1] != 0 ||
        data[1][0] != 0)
      return 1;
    return 0;
  }
  void f() {
    data[0][0] = 0;
    data[0][1] = data[1][0] = data[1][1] = 1;
  }
  void one() {
    init();
    for (int i = 0; i < num; i++) data[i][i] = 1;
  }
  inline void init() { memset(data, 0, sizeof(data)); }
} so;
mat copy(const mat& a) {
  mat c;
  for (int i = 0; i < num; i++)
    for (int j = 0; j < num; j++) c.data[i][j] = a.data[i][j];
  return c;
}
mat operator*(const mat& a, const mat& b) {
  mat c;
  c.init();
  for (int k = 0; k < num; k++) {
    for (int i = 0; i < num; i++) {
      if (!a.data[i][k]) continue;
      for (int j = 0; j < num; j++) {
        c.data[i][j] += a.data[i][k] * b.data[k][j];
        c.data[i][j] %= mod;
      }
    }
  }
  return c;
}
mat operator+(const mat& a, const mat& b) {
  mat c;
  for (int i = 0; i < num; i++)
    for (int j = 0; j < num; j++)
      c.data[i][j] = (a.data[i][j] + b.data[i][j]) % mod;
  return c;
}
mat operator^(const mat& aa, int k) {
  mat a = copy(aa);
  mat c;
  c.one();
  for (; k; k >>= 1) {
    if (k & 1) c = c * a;
    a = a * a;
  }
  return c;
}
const int maxl = 100005;
int n, q;
int da[maxl];
int fib(int x) {
  if (x < 3) return 1;
  mat a;
  a.f();
  mat tx = a ^ (x - 2);
  return (tx.data[1][0] + tx.data[1][1]) % mod;
}
int sum[maxl << 2][2];
mat ma[maxl << 2];
void pushup(int rt) {
  sum[rt][0] = (sum[rt << 1][0] + sum[rt << 1 | 1][0]) % mod;
  sum[rt][1] = (sum[rt << 1][1] + sum[rt << 1 | 1][1]) % mod;
}
void build(int l, int r, int rt) {
  ma[rt].one();
  if (l == r) {
    sum[rt][0] = fib(da[l]);
    sum[rt][1] = fib(da[l] + 1);
    return;
  }
  int m = (l + r) >> 1;
  build(l, m, rt << 1);
  build(m + 1, r, rt << 1 | 1);
  pushup(rt);
}
void mul(mat& m, int a, int b, int& fa, int& fb) {
  fa = (m.data[0][0] * a + m.data[0][1] * b) % mod;
  fb = (m.data[1][0] * a + m.data[1][1] * b) % mod;
}
void pushdown(int rt) {
  if (ma[rt].noone()) {
    mul(ma[rt], sum[rt << 1][0], sum[rt << 1][1], sum[rt << 1][0],
        sum[rt << 1][1]);
    mul(ma[rt], sum[rt << 1 | 1][0], sum[rt << 1 | 1][1], sum[rt << 1 | 1][0],
        sum[rt << 1 | 1][1]);
    ma[rt << 1] = ma[rt] * ma[rt << 1];
    ma[rt << 1 | 1] = ma[rt] * ma[rt << 1 | 1];
    ma[rt].one();
  }
}
void modify(int ql, int qr, int l, int r, int rt) {
  if (ql <= l && r <= qr) {
    mul(so, sum[rt][0], sum[rt][1], sum[rt][0], sum[rt][1]);
    ma[rt] = so * ma[rt];
    return;
  }
  pushdown(rt);
  int m = (l + r) >> 1;
  if (ql <= m) modify(ql, qr, l, m, rt << 1);
  if (qr > m) modify(ql, qr, m + 1, r, rt << 1 | 1);
  pushup(rt);
}
long long query(int ql, int qr, int l, int r, int rt) {
  if (ql <= l && r <= qr) {
    return sum[rt][0];
  }
  pushdown(rt);
  long long res = 0;
  int m = (l + r) >> 1;
  if (ql <= m) res += query(ql, qr, l, m, rt << 1);
  if (qr > m) res += query(ql, qr, m + 1, r, rt << 1 | 1);
  return res % mod;
}
int main() {
  int x, ty, l, r;
  scanf("%d%d", &n, &q);
  for (int i = 1; i <= n; i++) scanf("%d", da + i);
  build(1, n, 1);
  while (q--) {
    scanf("%d", &ty);
    if (ty == 1) {
      scanf("%d%d%d", &l, &r, &x);
      so.f();
      so = so ^ x;
      modify(l, r, 1, n, 1);
    } else {
      scanf("%d%d", &l, &r);
      printf("%d\n", query(l, r, 1, n, 1));
    }
  }
}
