#include <bits/stdc++.h>
using namespace std;
void in(int &x) {
  register int c = getchar();
  x = 0;
  for (; (c < 48 || c > 57); c = getchar())
    ;
  for (; c > 47 && c < 58; c = getchar()) {
    x = (x << 1) + (x << 3) + c - 48;
  }
}
const long long mod = 1e9 + 7;
struct fibmat {
  long long a, b, c, d;
  fibmat(long long p = 0, long long q = 0, long long r = 0, long long s = 0) {
    a = p;
    b = q;
    c = r;
    d = s;
  }
  fibmat operator+(fibmat &A) {
    fibmat B;
    B.a = (a + A.a) % mod;
    B.b = (b + A.b) % mod;
    B.c = (c + A.c) % mod;
    B.d = (d + A.d) % mod;
    return B;
  }
  fibmat operator*(fibmat &A) {
    fibmat B;
    B.a = ((a * A.a) % mod + (b * A.c) % mod) % mod;
    B.b = ((a * A.b) % mod + (b * A.d) % mod) % mod;
    B.c = ((c * A.a) % mod + (d * A.c) % mod) % mod;
    B.d = ((c * A.b) % mod + (d * A.d) % mod) % mod;
    return B;
  }
  bool operator==(fibmat &A) {
    return (A.a == a) && (A.b == b) && (A.c == c) && (A.d == d);
  }
  bool operator!=(fibmat &A) {
    return (A.a != a) || (A.b != b) || (A.c != c) || (A.d != d);
  }
};
fibmat mat_powmod(fibmat base, long long exp) {
  fibmat ret(1, 0, 0, 1);
  while (exp) {
    if (exp & 1) ret = ret * base;
    base = base * base;
    exp >>= 1;
  }
  return ret;
}
const int N = 1e5 + 5;
long long a[N];
fibmat st[N << 2], lazy[N << 2], init(1, 1, 1, 0), nil;
void build(long long i, long long begin, long long end) {
  if (begin == end)
    st[i] = mat_powmod(init, a[begin]);
  else {
    long long mid = begin + end >> 1;
    build(i << 1, begin, mid);
    build(i << 1 | 1, mid + 1, end);
    st[i] = st[i << 1] + st[i << 1 | 1];
  }
}
void updateRange(long long i, long long begin, long long end, long long l,
                 long long r, fibmat val) {
  if (lazy[i] != nil) {
    st[i] = st[i] * lazy[i];
    if (begin != end) {
      if (lazy[i << 1] == nil)
        lazy[i << 1] = lazy[i];
      else
        lazy[i << 1] = lazy[i << 1] * lazy[i];
      if (lazy[i << 1 | 1] == nil)
        lazy[i << 1 | 1] = lazy[i];
      else
        lazy[i << 1 | 1] = lazy[i << 1 | 1] * lazy[i];
    }
    lazy[i] = nil;
  }
  if (begin > r || end < l) return;
  if (begin >= l && end <= r) {
    st[i] = st[i] * val;
    if (begin != end) {
      if (lazy[i << 1] == nil)
        lazy[i << 1] = val;
      else
        lazy[i << 1] = lazy[i << 1] * val;
      if (lazy[i << 1 | 1] == nil)
        lazy[i << 1 | 1] = val;
      else
        lazy[i << 1 | 1] = lazy[i << 1 | 1] * val;
    }
  } else {
    int mid = begin + end >> 1;
    updateRange(i << 1, begin, mid, l, r, val);
    updateRange(i << 1 | 1, mid + 1, end, l, r, val);
    st[i] = st[i << 1] + st[i << 1 | 1];
  }
}
long long solve(long long i, long long begin, long long end, long long l,
                long long r) {
  if (begin > r || end < l) return 0;
  if (lazy[i] != nil) {
    st[i] = st[i] * lazy[i];
    if (begin != end) {
      if (lazy[i << 1] == nil)
        lazy[i << 1] = lazy[i];
      else
        lazy[i << 1] = lazy[i << 1] * lazy[i];
      if (lazy[i << 1 | 1] == nil)
        lazy[i << 1 | 1] = lazy[i];
      else
        lazy[i << 1 | 1] = lazy[i << 1 | 1] * lazy[i];
    }
    lazy[i] = nil;
  }
  if (begin >= l && end <= r) return st[i].b;
  long long mid = begin + end >> 1;
  return (solve(i << 1, begin, mid, l, r) +
          solve(i << 1 | 1, mid + 1, end, l, r)) %
         mod;
}
int main() {
  long long n, q, i, l, r, x;
  scanf(" %lld", &n);
  scanf(" %lld", &q);
  for (i = 0; i < n; i++) scanf(" %lld", &a[i]);
  build(1, 0, n - 1);
  while (q--) {
    scanf(" %lld", &i);
    scanf(" %lld", &l);
    scanf(" %lld", &r);
    if (i & 1) {
      scanf(" %lld", &x);
      updateRange(1, 0, n - 1, l - 1, r - 1, mat_powmod(init, x));
    } else
      printf("%lld\n", solve(1, 0, n - 1, l - 1, r - 1));
  }
  return 0;
}
