#include <bits/stdc++.h>
using namespace std;
int N, M, sz = 1;
struct MAT {
  int f[2][2];
  MAT() {
    f[0][0] = 0;
    f[0][1] = 0;
    f[1][0] = 0;
    f[1][1] = 0;
  }
  MAT(int a, int b, int c, int d) {
    f[0][0] = a;
    f[0][1] = b;
    f[1][0] = c;
    f[1][1] = d;
  }
};
vector<MAT> segm, lazy;
void matAdd(MAT &a, MAT &b, MAT &c) {
  a.f[0][0] = (b.f[0][0] + c.f[0][0]) % 1000000007;
  a.f[0][1] = (b.f[0][1] + c.f[0][1]) % 1000000007;
  a.f[1][0] = (b.f[1][0] + c.f[1][0]) % 1000000007;
  a.f[1][1] = (b.f[1][1] + c.f[1][1]) % 1000000007;
}
void matMul(MAT &a, MAT &b, MAT &c) {
  a = MAT(((1ll * c.f[0][0] * b.f[0][0]) % 1000000007 +
           (1ll * c.f[0][1] * b.f[1][0]) % 1000000007) %
              1000000007,
          ((1ll * c.f[0][0] * b.f[0][1]) % 1000000007 +
           (1ll * c.f[0][1] * b.f[1][1]) % 1000000007) %
              1000000007,
          ((1ll * c.f[1][0] * b.f[0][0]) % 1000000007 +
           (1ll * c.f[1][1] * b.f[1][0]) % 1000000007) %
              1000000007,
          ((1ll * c.f[1][0] * b.f[0][1]) % 1000000007 +
           (1ll * c.f[1][1] * b.f[1][1]) % 1000000007) %
              1000000007);
}
void init(MAT &ret, int x) {
  ret.f[0][0] = 1;
  ret.f[0][1] = 0;
  ret.f[1][0] = 0;
  ret.f[1][1] = 1;
  MAT y = MAT(1, 1, 1, 0);
  while (x) {
    if (x & 1) {
      matMul(ret, ret, y);
      x--;
    }
    matMul(y, y, y);
    x = x >> 1;
  }
}
void build_segm(int node, int l, int r) {
  if (l < r - 1) {
    int mid = (l + r) >> 1;
    build_segm(2 * node + 1, l, mid);
    build_segm(2 * node + 2, mid, r);
    matAdd(segm[node], segm[2 * node + 1], segm[2 * node + 2]);
  }
}
void update(int node, int l, int r, int start, int end, MAT x) {
  if (lazy[node].f[0][1] != 0) {
    if (l < r - 1) {
      matMul(segm[node * 2 + 1], segm[node * 2 + 1], lazy[node]);
      matMul(segm[node * 2 + 2], segm[node * 2 + 2], lazy[node]);
      matMul(lazy[node * 2 + 1], lazy[node * 2 + 1], lazy[node]);
      matMul(lazy[node * 2 + 2], lazy[node * 2 + 2], lazy[node]);
    }
    lazy[node].f[0][0] = 1;
    lazy[node].f[0][1] = 0;
    lazy[node].f[1][0] = 0;
    lazy[node].f[1][1] = 1;
  }
  if (l > end || r - 1 < start) return;
  if (start <= l && r - 1 <= end) {
    matMul(segm[node], segm[node], x);
    if (l < r - 1) matMul(lazy[node], lazy[node], x);
    return;
  }
  int mid = (l + r) >> 1;
  update(2 * node + 1, l, mid, start, end, x);
  update(2 * node + 2, mid, r, start, end, x);
  matAdd(segm[node], segm[2 * node + 1], segm[2 * node + 2]);
}
int sum(int node, int l, int r, int start, int end) {
  if (lazy[node].f[0][1] != 0) {
    if (l < r - 1) {
      matMul(segm[node * 2 + 1], segm[node * 2 + 1], lazy[node]);
      matMul(segm[node * 2 + 2], segm[node * 2 + 2], lazy[node]);
      matMul(lazy[node * 2 + 1], lazy[node * 2 + 1], lazy[node]);
      matMul(lazy[node * 2 + 2], lazy[node * 2 + 2], lazy[node]);
    }
    lazy[node].f[0][0] = 1;
    lazy[node].f[0][1] = 0;
    lazy[node].f[1][0] = 0;
    lazy[node].f[1][1] = 1;
  }
  if (l > end || r - 1 < start) return 0;
  if (start <= l && r - 1 <= end) return segm[node].f[1][1];
  int mid = (l + r) >> 1;
  return (sum(2 * node + 1, l, mid, start, end) +
          sum(2 * node + 2, mid, r, start, end)) %
         1000000007;
}
int main() {
  MAT temp;
  int t, l, r, x;
  scanf("%d %d", &N, &M);
  while (sz < N) sz *= 2;
  segm = vector<MAT>(sz * 2 - 1);
  lazy = vector<MAT>(sz * 2 - 1);
  for (int i = 0; i < sz * 2 - 1; i++)
    lazy[i].f[0][0] = 1, lazy[i].f[0][1] = 0, lazy[i].f[1][0] = 0,
    lazy[i].f[1][1] = 1;
  for (int i = 0; i < N; i++) {
    scanf("%d", &x);
    init(segm[i + sz - 1], x + 1);
  }
  for (int i = N; i < sz; i++) segm[i + sz - 1] = MAT();
  build_segm(0, 0, sz);
  for (int i = 0; i < M; i++) {
    scanf("%d", &t);
    if (t == 1) {
      scanf("%d %d %d", &l, &r, &x);
      init(temp, x);
      update(0, 0, sz, l - 1, r - 1, temp);
    } else if (t == 2) {
      scanf("%d %d", &l, &r);
      printf("%d\n", sum(0, 0, sz, l - 1, r - 1));
    }
  }
  return 0;
}
