#include <bits/stdc++.h>
using namespace std;
const int N = 100000 + 10;
const long long MOD = 1000000007;
struct mat {
  long long a[2][2];
  mat() {
    a[0][0] = a[1][1] = 1;
    a[0][1] = a[1][0] = 0;
  }
  mat operator*(const mat p) {
    mat ret;
    for (int i = 0; i < 2; i++)
      for (int j = 0; j < 2; j++) {
        ret.a[i][j] = 0;
        for (int k = 0; k < 2; k++) ret.a[i][j] += a[i][k] * p.a[k][j] % MOD;
        ret.a[i][j] %= MOD;
      }
    return ret;
  }
  mat operator+(const mat p) {
    mat ret;
    for (int i = 0; i < 2; i++)
      for (int j = 0; j < 2; j++) {
        ret.a[i][j] = a[i][j] + p.a[i][j];
        if (ret.a[i][j] >= MOD) ret.a[i][j] -= MOD;
      }
    return ret;
  }
  bool operator!=(const mat p) {
    for (int i = 0; i < 2; i++)
      for (int j = 0; j < 2; j++)
        if (a[i][j] != p.a[i][j]) return 1;
    return 0;
  }
  void output() {
    puts("===========");
    for (int i = 0; i < 2; ++i) {
      for (int j = 0; j < 2; j++) printf("%10I64d ", a[i][j]);
      puts("");
    }
    puts("+++++++++++");
  }
};
mat tree[N << 2], tag[N << 2];
mat base, diag;
int a[N], n, m;
int p, q;
mat dt;
inline mat fpow(mat base, int n) {
  mat ret, b = base;
  ret.a[0][0] = ret.a[1][1] = 1;
  ret.a[1][0] = ret.a[0][1] = 0;
  while (n) {
    if (n & 1) ret = ret * b;
    b = b * b;
    n >>= 1;
  }
  return ret;
}
void build(int v, int L, int R) {
  if (L == R) {
    tree[v] = fpow(base, a[L]);
    tag[v] = diag;
    return;
  }
  int mid = (L + R) >> 1, Ls = v << 1, Rs = Ls | 1;
  build(Ls, L, mid);
  build(Rs, mid + 1, R);
  tree[v] = tree[Ls] + tree[Rs];
  tag[v] = diag;
}
void modify(int v, int L, int R) {
  if (p <= L && R <= q) {
    tree[v] = tree[v] * dt;
    tag[v] = tag[v] * dt;
    return;
  }
  int mid = (L + R) >> 1, Ls = v << 1, Rs = Ls | 1;
  if (tag[v] != diag) {
    tree[Ls] = tree[Ls] * tag[v];
    tag[Ls] = tag[Ls] * tag[v];
    tree[Rs] = tree[Rs] * tag[v];
    tag[Rs] = tag[Rs] * tag[v];
    tag[v] = diag;
  }
  if (p <= mid) modify(Ls, L, mid);
  if (q > mid) modify(Rs, mid + 1, R);
  tree[v] = tree[Ls] + tree[Rs];
}
mat query(int v, int L, int R) {
  if (p <= L && R <= q) return tree[v];
  int mid = (L + R) >> 1, Ls = v << 1, Rs = Ls | 1;
  if (tag[v] != diag) {
    tree[Ls] = tree[Ls] * tag[v];
    tag[Ls] = tag[Ls] * tag[v];
    tree[Rs] = tree[Rs] * tag[v];
    tag[Rs] = tag[Rs] * tag[v];
    tag[v] = diag;
  }
  if (q <= mid) return query(Ls, L, mid);
  if (p > mid) return query(Rs, mid + 1, R);
  return query(Ls, L, mid) + query(Rs, mid + 1, R);
}
int main() {
  base.a[0][0] = base.a[0][1] = base.a[1][0] = 1;
  base.a[1][1] = 0;
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
  build(1, 1, n);
  int op, x;
  for (int i = 1; i <= m; i++) {
    scanf("%d", &op);
    if (op == 1) {
      scanf("%d %d %d", &p, &q, &x);
      dt = fpow(base, x);
      modify(1, 1, n);
    } else {
      scanf("%d %d", &p, &q);
      mat ans = query(1, 1, n);
      printf("%I64d\n", ans.a[1][0]);
    }
  }
  return 0;
}
