#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1000000007LL;
int n, m;
long long a[100001];
long long cnt = 0LL;
struct M {
  long long t[2][2];
  long long *operator[](int x) { return t[x]; }
  M() { memset(t, 0, sizeof(t)); }
  void print() {
    printf("%.10I64d | %.10I64d\n", t[0][0], t[0][1]);
    printf("%.10I64d | %.10I64d\n", t[1][0], t[1][1]);
  }
  M unitM() {
    M C;
    C[0][0] = C[1][1] = 1LL;
    C[0][1] = C[1][0] = 0LL;
    return C;
  }
} F, U, K;
inline M operator+(M A, M B) {
  M C;
  C[0][0] = (A[0][0] + B[0][0]) % MOD;
  C[0][1] = (A[0][1] + B[0][1]) % MOD;
  return C;
}
inline void operator+=(M &A, M B) {
  M C;
  C[0][0] = (A[0][0] + B[0][0]) % MOD;
  C[0][1] = (A[0][1] + B[0][1]) % MOD;
  A = C;
}
inline M operator*(M A, M B) {
  M C;
  for (int i = 0; i < 2; i++)
    for (int k = 0; k < 2; k++)
      for (int j = 0; j < 2; j++) C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % MOD;
  return C;
}
inline void operator*=(M &A, M B) {
  M C;
  for (int i = 0; i < 2; i++)
    for (int k = 0; k < 2; k++)
      for (int j = 0; j < 2; j++) C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % MOD;
  A = C;
}
inline M qm(M A, long long x) {
  M ret = A.unitM();
  while (x) {
    if (x & 1LL) ret *= A;
    A *= A;
    x >>= 1;
  }
  return ret;
}
struct Node {
  int lc, rc, l, r;
  M sum;
  M delta;
} t[400010];
inline void update(int x) {
  if (t[x].lc) {
    t[t[x].lc].sum *= t[x].delta;
    t[t[x].lc].delta *= t[x].delta;
  }
  if (t[x].rc) {
    t[t[x].rc].sum *= t[x].delta;
    t[t[x].rc].delta *= t[x].delta;
  }
  t[x].delta = t[x].delta.unitM();
}
void change(int x, int l, int r) {
  if (l >= t[x].r || r <= t[x].l) return;
  if (l <= t[x].l && t[x].r <= r) {
    t[x].delta *= K;
    t[x].sum *= K;
  } else {
    update(x);
    int mid = (t[x].l + t[x].r) >> 1;
    if (l < mid) change(t[x].lc, l, r);
    if (r > mid) change(t[x].rc, l, r);
    t[x].sum = t[t[x].lc].sum + t[t[x].rc].sum;
  }
}
long long query(int x, int l, int r) {
  if (l >= t[x].r || r <= t[x].l) return 0;
  if (l <= t[x].l && t[x].r <= r) {
    return t[x].sum[0][0];
  } else {
    update(x);
    long long ret = 0LL;
    int mid = (t[x].l + t[x].r) >> 1;
    if (l < mid) ret = (ret + query(t[x].lc, l, r)) % MOD;
    if (r > mid) ret = (ret + query(t[x].rc, l, r)) % MOD;
    return ret;
  }
}
void build(int x, int l, int r) {
  t[x].delta = t[x].delta.unitM();
  t[x].l = l;
  t[x].r = r;
  if (l + 1 == r) {
    t[x].lc = t[x].rc = 0;
    t[x].sum = U * qm(F, a[l]);
  } else {
    int mid = (l + r) >> 1;
    t[x].lc = (x << 1) + 1;
    t[x].rc = (x << 1) + 2;
    build(t[x].lc, l, mid);
    build(t[x].rc, mid, r);
    t[x].sum = t[t[x].lc].sum + t[t[x].rc].sum;
  }
}
int main() {
  F[0][0] = F[0][1] = F[1][0] = 1LL;
  U[0][1] = 1LL;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) scanf("%I64d", &a[i]);
  build(0, 1, n + 1);
  while (m--) {
    int order, l, r;
    scanf("%d%d%d", &order, &l, &r);
    if (order == 1) {
      long long x;
      scanf("%I64d", &x);
      K = qm(F, x);
      change(0, l, r + 1);
    } else {
      printf("%I64d\n", query(0, l, r + 1));
    }
  }
  return 0;
}
