#include <bits/stdc++.h>
using namespace std;
int n, m;
struct Matrix {
  int num[2][2];
} tran, e, a[200010], t[4 * 200010], lzy[4 * 200010];
inline int Read() {
  char c = getchar();
  int num = 0;
  while ('0' > c || c > '9') c = getchar();
  while ('0' <= c && c <= '9') num = num * 10 + c - '0', c = getchar();
  return (num);
}
Matrix operator+(Matrix a, Matrix b) {
  Matrix c;
  memset(c.num, 0, sizeof(c.num));
  for (int i = 0; i < 2; i++)
    for (int j = 0; j < 2; j++)
      c.num[i][j] = (a.num[i][j] + b.num[i][j]) % 1000000007;
  return (c);
}
Matrix operator*(Matrix a, Matrix b) {
  Matrix c;
  memset(c.num, 0, sizeof(c.num));
  for (int k = 0; k < 2; k++)
    for (int i = 0; i < 2; i++)
      for (int j = 0; j < 2; j++)
        c.num[i][j] =
            (c.num[i][j] + a.num[i][k] * 1ll * b.num[k][j] % 1000000007) %
            1000000007;
  return (c);
}
inline Matrix Ksm(int x) {
  Matrix xx = e, xxx = tran;
  while (x) {
    if (x & 1) xx = xx * xxx;
    xxx = xxx * xxx;
    x /= 2;
  }
  return (xx);
}
inline void Down(int rt) {
  int L = rt * 2, R = rt * 2 + 1;
  t[L] = t[L] * lzy[rt], lzy[L] = lzy[L] * lzy[rt];
  t[R] = t[R] * lzy[rt], lzy[R] = lzy[R] * lzy[rt];
  lzy[rt] = e;
}
inline void Build(int rt, int l, int r) {
  lzy[rt] = e;
  int mid = (l + r) / 2;
  if (l == r) {
    t[rt] = a[l];
    return;
  }
  Build(rt * 2, l, mid);
  Build(rt * 2 + 1, mid + 1, r);
  t[rt] = t[rt * 2] + t[rt * 2 + 1];
}
inline void Add(int rt, int l, int r, int a, int b, Matrix x) {
  int mid = (l + r) / 2;
  if (l == a && r == b) {
    t[rt] = t[rt] * x;
    lzy[rt] = lzy[rt] * x;
    return;
  }
  Down(rt);
  if (b <= mid) Add(rt * 2, l, mid, a, b, x);
  if (mid < a) Add(rt * 2 + 1, mid + 1, r, a, b, x);
  if (a <= mid && mid < b)
    Add(rt * 2, l, mid, a, mid, x), Add(rt * 2 + 1, mid + 1, r, mid + 1, b, x);
  t[rt] = t[rt * 2] + t[rt * 2 + 1];
}
inline Matrix Ask(int rt, int l, int r, int a, int b) {
  int mid = (l + r) / 2;
  if (l == a && r == b) return (t[rt]);
  Down(rt);
  if (b <= mid) return (Ask(rt * 2, l, mid, a, b));
  if (mid < a) return (Ask(rt * 2 + 1, mid + 1, r, a, b));
  if (a <= mid && mid < b) {
    Matrix L = Ask(rt * 2, l, mid, a, mid);
    Matrix R = Ask(rt * 2 + 1, mid + 1, r, mid + 1, b);
    return (L + R);
  }
}
int main() {
  n = Read();
  m = Read();
  e.num[0][0] = e.num[1][1] = 1;
  tran.num[0][0] = tran.num[1][0] = tran.num[0][1] = 1;
  for (int j, i = 1; i <= n; i++) a[i] = Ksm(Read());
  Build(1, 1, n);
  for (int i = 1; i <= m; i++) {
    int op = Read();
    if (op == 1) {
      int l = Read(), r = Read(), k = Read();
      Add(1, 1, n, l, r, Ksm(k));
    } else {
      int l = Read(), r = Read();
      Matrix x = Ask(1, 1, n, l, r);
      Matrix a;
      memset(a.num, 0, sizeof(a.num));
      a.num[0][1] = 1;
      a = a * x;
      printf("%d\n", a.num[0][0]);
    }
  }
}
