#include <bits/stdc++.h>
using namespace std;
__inline string next_line() {
  const int SIZE = 1100000;
  static char buf[SIZE + 1];
  static int p = SIZE;
  string res;
  int f = 1;
  while ((p < SIZE || (p = 0, buf[fread(buf, 1, SIZE, stdin)] = 0, buf[0])) &&
         (buf[p] != '\n' && (res += buf[p], f = 0, 1) || f))
    ++p;
  return res;
}
const int INF = 0x3f3f3f3f;
const double eps = 1e-8;
const double PI = acos(-1.0);
const int MAXN = 1e5 + 5;
const int MOD = 1e9 + 7;
int sgn(double x) {
  if (fabs(x) < eps) return 0;
  if (x < 0)
    return -1;
  else
    return 1;
}
struct Mat {
  long long x[2][2];
  void init() {
    x[0][0] = x[1][1] = 1;
    x[1][0] = x[0][1] = 0;
  }
  Mat operator*(const Mat &b) const {
    Mat c;
    memset(c.x, 0, sizeof(c.x));
    for (int k = 0; k < 2; k++)
      for (int i = 0; i < 2; i++)
        for (int j = 0; j < 2; j++)
          c.x[i][j] = (c.x[i][j] + x[i][k] * b.x[k][j]) % MOD;
    return c;
  }
  Mat operator+(const Mat &b) const {
    Mat c;
    for (int i = 0; i < 2; i++)
      for (int j = 0; j < 2; j++) c.x[i][j] = (x[i][j] + b.x[i][j]) % MOD;
    return c;
  }
} sum[MAXN << 2], lazy[MAXN << 2];
int n, m, a[MAXN];
Mat pw(int n) {
  Mat A, E;
  E.init();
  A.x[0][0] = A.x[0][1] = A.x[1][0] = 1;
  A.x[1][1] = 0;
  while (n) {
    if (n & 1) E = E * A;
    A = A * A;
    n >>= 1;
  }
  return E;
}
void PushUp(int rt) { sum[rt] = sum[rt << 1] + sum[rt << 1 | 1]; }
void PushDown(int rt) {
  sum[rt << 1] = sum[rt << 1] * lazy[rt];
  sum[rt << 1 | 1] = sum[rt << 1 | 1] * lazy[rt];
  lazy[rt << 1] = lazy[rt << 1] * lazy[rt];
  lazy[rt << 1 | 1] = lazy[rt << 1 | 1] * lazy[rt];
  lazy[rt].init();
}
void Build(int l, int r, int rt) {
  sum[rt].init();
  lazy[rt].init();
  if (l == r) {
    sum[rt] = pw(a[l] - 1);
    return;
  }
  int mid = l + r >> 1;
  Build(l, mid, rt << 1);
  Build(mid + 1, r, rt << 1 | 1);
  PushUp(rt);
}
void UpDate(int L, int R, Mat x, int l, int r, int rt) {
  if (L <= l && r <= R) {
    sum[rt] = sum[rt] * x;
    lazy[rt] = lazy[rt] * x;
    return;
  }
  PushDown(rt);
  int mid = l + r >> 1;
  if (L <= mid) UpDate(L, R, x, l, mid, rt << 1);
  if (R > mid) UpDate(L, R, x, mid + 1, r, rt << 1 | 1);
  PushUp(rt);
}
long long Query(int L, int R, int l, int r, int rt) {
  if (L <= l && r <= R) {
    return sum[rt].x[0][0];
  }
  PushDown(rt);
  int mid = l + r >> 1;
  long long ret = 0;
  if (L <= mid) ret = (ret + Query(L, R, l, mid, rt << 1)) % MOD;
  if (R > mid) ret = (ret + Query(L, R, mid + 1, r, rt << 1 | 1)) % MOD;
  PushUp(rt);
  return ret;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
  Build(1, n, 1);
  int op, l, r, x;
  while (m--) {
    scanf("%d", &op);
    if (op == 1) {
      scanf("%d%d%d", &l, &r, &x);
      Mat tmp = pw(x);
      UpDate(l, r, tmp, 1, n, 1);
    } else {
      scanf("%d%d", &l, &r);
      printf("%I64d\n", Query(l, r, 1, n, 1));
    }
  }
}
