#include <bits/stdc++.h>
using namespace std;
inline void read(int &x) {
  register char c = getchar();
  x = 0;
  for (; c < '0' || c > '9'; c = getchar())
    ;
  for (; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + c - '0';
}
inline void write(int x) {
  char c[10], *p = c;
  do {
    *p++ = '0' + x % 10;
    x /= 10;
  } while (x);
  do {
    putchar(*--p);
  } while (p > c);
  putchar('\n');
}
const long long M = 1e9 + 7;
struct Mat {
  Mat() : a(1), b(0), c(0), d(1) {}
  Mat(long long a, long long b, long long c, long long d)
      : a(a), b(b), c(c), d(d) {}
  long long a, b, c, d;
};
Mat operator*(Mat x, Mat y) {
  return Mat((x.a * y.a + x.b * y.c) % M, (x.a * y.b + x.b * y.d) % M,
             (x.c * y.a + x.d * y.c) % M, (x.c * y.b + x.d * y.d) % M);
}
Mat operator+(Mat x, Mat y) {
  return Mat((x.a + y.a) % M, (x.b + y.b) % M, (x.c + y.c) % M,
             (x.d + y.d) % M);
}
Mat matpow(Mat a, int e) {
  Mat z(1, 0, 0, 1);
  while (e) {
    if (e % 2) z = z * a;
    e /= 2;
    a = a * a;
  }
  return z;
}
const int N = 1 << 17;
Mat X, F(0, 1, 1, 1), T[N * 2], A[N * 2];
Mat query(int a, int b, int v = 1, int sz = N) {
  if (a <= 0 && b >= sz) return T[v];
  if (a >= sz || b <= 0) return Mat(0, 0, 0, 0);
  sz /= 2;
  return (query(a, b, v + v, sz) + query(a - sz, b - sz, v + v + 1, sz)) * A[v];
}
void mul(int a, int b, int v = 1, int sz = N) {
  if (a >= sz || b <= 0) return;
  if (a <= 0 && b >= sz) {
    A[v] = A[v] * X;
    T[v] = T[v] * X;
    return;
  }
  sz /= 2;
  mul(a, b, v + v, sz);
  mul(a - sz, b - sz, v + v + 1, sz);
  T[v] = A[v] * (T[v + v] + T[v + v + 1]);
}
int main() {
  int n, m, l, r;
  read(n);
  read(m);
  for (l = 0; l != n; ++l) {
    read(r);
    X = matpow(F, r);
    mul(l, l + 1);
  }
  while (m--) {
    read(n);
    read(l);
    read(r);
    if (n != 2) {
      read(n);
      X = matpow(F, n);
      mul(l - 1, r);
    } else
      write((int)query(l - 1, r).b);
  }
}
