#include <bits/stdc++.h>
template <class T>
inline void rd(T &x) {
  char c = getchar();
  x = 0;
  while (!isdigit(c)) c = getchar();
  while (isdigit(c)) {
    x = x * 10 + c - '0';
    c = getchar();
  }
}
inline void ou(long long x) {
  if (x > 9) ou(x / 10);
  putchar(x % 10 + '0');
}
const int N = 1e5 + 100;
const int M = 1e9 + 7;
using namespace std;
void ha(long long &a, long long b) {
  a += b;
  if (a >= M) a -= M;
}
struct mat {
  long long a[2][2];
  mat(int tag = 0) {
    if (tag == 1)
      a[0][0] = a[0][1] = a[1][0] = 1, a[1][1] = 0;
    else if (tag == 0)
      memset(a, 0, sizeof(a));
    else
      a[0][1] = a[1][0] = 0, a[0][0] = a[1][1] = 1;
  }
  mat operator+(const mat b) {
    for (int i = 0; i < 2; i++)
      for (int j = 0; j < 2; j++) ha(a[i][j], b.a[i][j]);
    return *this;
  }
  mat operator*(const mat b) {
    mat c;
    for (int i = 0; i < 2; i++)
      for (int j = 0; j < 2; j++)
        if (a[i][j])
          for (int k = 0; k < 2; k++) (c.a[i][k] += a[i][j] * b.a[j][k]) %= M;
    return c;
  }
  void show() {
    puts("----------");
    for (int i = 0; i < 2; i++) {
      for (int j = 0; j < 2; j++) cout << a[i][j] << " ";
      puts("");
    }
    puts("----------");
  }
};
mat qpow(long long k) {
  mat ret(2), a(1);
  while (k) {
    if (k & 1) ret = ret * a;
    a = a * a;
    k >>= 1;
  }
  return ret;
}
mat f[N << 2], yo[N << 2];
int lazy[N << 2];
int n, m;
int a[N];
mat zero(0), one(2);
mat build(int l = 1, int r = n, int p = 1) {
  lazy[p] = 0;
  yo[p] = one;
  if (l == r) return f[p] = qpow(a[l]);
  int mid = l + r >> 1;
  return f[p] = build(l, mid, 2 * p) + build(mid + 1, r, 2 * p + 1);
}
void add(int z, int y, mat dt, int l = 1, int r = n, int p = 1) {
  int mid = l + r >> 1;
  if (z <= l && r <= y) {
    yo[p] = yo[p] * dt;
    return;
  }
  lazy[p] = 1;
  if (z > mid) {
    add(z, y, dt, mid + 1, r, 2 * p + 1);
    return;
  }
  if (y <= mid) {
    add(z, y, dt, l, mid, 2 * p);
    return;
  }
  add(z, y, dt, l, mid, 2 * p);
  add(z, y, dt, mid + 1, r, 2 * p + 1);
}
mat qry(int z, int y, mat tot, int l = 1, int r = n, int p = 1) {
  int mid = l + r >> 1;
  mat ntot = tot * yo[p];
  if (z <= l && r <= y) {
    if (lazy[p]) {
      lazy[p] = 0;
      f[p] =
          qry(z, y, one, mid + 1, r, 2 * p + 1) + qry(z, y, one, l, mid, 2 * p);
    }
    return f[p] * ntot;
  }
  if (z > mid) return qry(z, y, ntot, mid + 1, r, 2 * p + 1);
  if (y <= mid) return qry(z, y, ntot, l, mid, 2 * p);
  return qry(z, y, ntot, mid + 1, r, 2 * p + 1) +
         qry(z, y, ntot, l, mid, 2 * p);
}
int main() {
  rd(n);
  rd(m);
  for (int i = 1; i < n + 1; i++) rd(a[i]);
  build();
  for (int i = 0; i < m; i++) {
    int id, dt, y, z;
    rd(id);
    if (id == 1) {
      rd(z);
      rd(y);
      rd(dt);
      add(z, y, qpow(dt));
    } else {
      rd(z);
      rd(y);
      ou(qry(z, y, one).a[0][1]);
      puts("");
    }
  }
  return 0;
}
