#include <bits/stdc++.h>
using namespace std;
int n, m, tmp;
struct Martix {
  long long a[2][2];
  Martix() { memset(a, 0, sizeof(a)); }
  void init() {
    for (int i = 0; i < 2; i++) {
      for (int j = 0; j < 2; j++) {
        a[i][j] = (j == i);
      }
    }
  }
  Martix operator+(const Martix &b) const {
    Martix c;
    for (int i = 0; i < 2; i++) {
      for (int j = 0; j < 2; j++) {
        c.a[i][j] = (a[i][j] + b.a[i][j]) % 1000000007;
      }
    }
    return c;
  }
  Martix operator*(const Martix &b) const {
    Martix c;
    for (int i = 0; i < 2; i++) {
      for (int k = 0; k < 2; k++) {
        for (int j = 0; j < 2; j++) {
          c.a[i][j] =
              (c.a[i][j] + (a[i][k] * b.a[k][j]) % 1000000007) % 1000000007;
        }
      }
    }
    return c;
  }
  Martix operator^(const int &t) const {
    Martix A, ans;
    ans.init();
    A.a[0][0] = A.a[1][0] = A.a[0][1] = 1;
    int p = t;
    while (p) {
      if (p & 1) ans = ans * A;
      A = A * A;
      p >>= 1;
    }
    return ans;
  }
};
Martix f, sum[100010 << 2], lazy[100010 << 2];
void pushup(int rt) { sum[rt] = sum[rt << 1] + sum[rt << 1 | 1]; }
void pushdown(int rt) {
  sum[rt << 1] = lazy[rt] * sum[rt << 1];
  sum[rt << 1 | 1] = lazy[rt] * sum[rt << 1 | 1];
  lazy[rt << 1] = lazy[rt] * lazy[rt << 1];
  lazy[rt << 1 | 1] = lazy[rt] * lazy[rt << 1 | 1];
  lazy[rt].init();
}
void build(int l, int r, int rt) {
  lazy[rt].init();
  if (l == r) {
    scanf("%d", &tmp);
    sum[rt] = f ^ (tmp - 1);
    return;
  }
  pushdown(rt);
  int mid = (l + r) / 2;
  build(l, mid, rt << 1);
  build(mid + 1, r, rt << 1 | 1);
  pushup(rt);
}
void update(int l, int r, int rt, int L, int R, Martix x) {
  if (L <= l && r <= R) {
    sum[rt] = x * sum[rt];
    lazy[rt] = x * lazy[rt];
    return;
  }
  pushdown(rt);
  int mid = (l + r) / 2;
  if (L <= mid) update(l, mid, rt << 1, L, R, x);
  if (R > mid) update(mid + 1, r, rt << 1 | 1, L, R, x);
  pushup(rt);
}
long long query(int l, int r, int rt, int L, int R) {
  if (L <= l && r <= R) {
    return sum[rt].a[0][0];
  }
  pushdown(rt);
  int mid = (l + r) / 2;
  long long res = 0;
  if (L <= mid) res = (res + query(l, mid, rt << 1, L, R)) % 1000000007;
  if (R > mid) res = (res + query(mid + 1, r, rt << 1 | 1, L, R)) % 1000000007;
  pushup(rt);
  return res;
}
int main() {
  scanf("%d %d", &n, &m);
  f.a[0][0] = f.a[1][0] = f.a[0][1] = 1;
  build(1, n, 1);
  int op, x, y, z;
  while (m--) {
    scanf("%d", &op);
    if (op == 1) {
      scanf("%d %d %d", &x, &y, &z);
      update(1, n, 1, x, y, f ^ z);
    } else {
      scanf("%d %d", &x, &y);
      printf("%I64d\n", query(1, n, 1, x, y));
    }
  }
  return 0;
}
