#include <bits/stdc++.h>
using namespace std;
struct matrix {
  long long a, b, c, d;
  matrix(){};
  matrix(long long a, long long b, long long c, long long d)
      : a(a), b(b), c(c), d(d){};
  matrix operator%(long long m) const {
    return matrix(a % m, b % m, c % m, d % m);
  }
  matrix operator+(matrix m) const {
    return matrix(a + m.a, b + m.b, c + m.c, d + m.d) % 1000000007ll;
  }
  matrix operator*(matrix m) const {
    return matrix(a * m.a + b * m.c, a * m.b + b * m.d, c * m.a + d * m.c,
                  c * m.b + d * m.d) %
           1000000007ll;
  }
} r[55], rr[1000001], f0;
matrix raise(long long k) {
  matrix ret = matrix(1, 0, 0, 1);
  for (int i = 50; i >= 0; i--) {
    if (k <= 1000000) {
      break;
    }
    if (k >= (1ll << i)) {
      k -= (1ll << i);
      ret = ret * r[i];
    }
  }
  return ret * rr[k];
}
long long mode, a[100001], n, m, x, y, z, lazy[4 * 100001];
matrix data[4 * 100001];
struct segment_tree {
  void merge(int id) { data[id] = data[id * 2] + data[id * 2 + 1]; }
  void push(int id, int l, int r) {
    data[id * 2] = data[id * 2] * raise(lazy[id]);
    data[id * 2 + 1] = data[id * 2 + 1] * raise(lazy[id]);
    lazy[id * 2] += lazy[id];
    lazy[id * 2 + 1] += lazy[id];
    lazy[id] = 0;
  }
  void build(int id, int l, int r) {
    if (r == l) {
      data[id] = f0 * raise(a[l]);
      return;
    }
    build(id * 2, l, (l + r) / 2);
    build(id * 2 + 1, (l + r) / 2 + 1, r);
    merge(id);
  }
  void update(int id, int l, int r, int a, int b, long long v) {
    if (r < a || b < l) return;
    if (a <= l && r <= b) {
      data[id] = data[id] * raise(v);
      lazy[id] += v;
      return;
    }
    push(id, l, r);
    update(id * 2, l, (l + r) / 2, a, b, v);
    update(id * 2 + 1, (l + r) / 2 + 1, r, a, b, v);
    merge(id);
  }
  matrix query(int id, int l, int r, int a, int b) {
    if (r < a || b < l) return matrix(0, 0, 0, 0);
    if (a <= l && r <= b) return data[id];
    push(id, l, r);
    return query(id * 2, l, (l + r) / 2, a, b) +
           query(id * 2 + 1, (l + r) / 2 + 1, r, a, b);
  }
} smt;
int main() {
  f0 = matrix(1, 0, 0, 0);
  r[0] = matrix(1, 1, 1, 0);
  rr[0] = matrix(1, 0, 0, 1);
  for (int i = 1; i <= 50; i++) {
    r[i] = r[i - 1] * r[i - 1];
  }
  for (int i = 1; i <= 1000000; i++) {
    rr[i] = rr[i - 1] * matrix(1, 1, 1, 0);
  }
  scanf("%lld%lld", &n, &m);
  for (int i = 1; i <= n; i++) {
    scanf("%lld", &a[i]);
    a[i]--;
  }
  smt.build(1, 1, n);
  for (int i = 1; i <= m; i++) {
    scanf("%lld", &mode);
    if (mode == 1) {
      scanf("%lld%lld%lld", &x, &y, &z);
      smt.update(1, 1, n, x, y, z);
    } else {
      scanf("%lld%lld", &x, &y);
      printf("%lld\n", smt.query(1, 1, n, x, y).a);
    }
  }
  return 0;
}
