#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1000000007;
const int MAX = 100005;
template <class T>
struct matrix {
  int rows, columns;
  T mod;
  T grid[2][2];
  matrix() { grid[0][0] = grid[0][1] = grid[1][0] = grid[1][1] = 0; }
  matrix(int rows_, int columns_, T mod_) {
    rows = rows_;
    columns = columns_;
    mod = mod_;
    grid[0][0] = grid[0][1] = grid[1][0] = grid[1][1] = 0;
  }
  inline matrix<T> operator*(const matrix<T> &other) const {
    matrix<T> ret(rows, other.columns, mod);
    for (int i = 0; i < rows; i++)
      for (int j = 0; j < other.columns; j++)
        for (int k = 0; k < columns; k++)
          ret.grid[i][j] =
              (ret.grid[i][j] + grid[i][k] * 1ll * other.grid[k][j]) % mod;
    return ret;
  }
  inline matrix<T> power(long long p) {
    assert(p != 0);
    if (p == 1) {
      matrix<T> ret = (*this);
      return ret;
    }
    matrix<T> ret = power(p / 2);
    ret = ret * ret;
    if (p & 1) ret = ret * (*this);
    return ret;
  }
  void print() {
    for (int i = 0; i < rows; i++)
      for (int j = 0; j < columns; j++)
        cout << grid[i][j] << " \n"[j == columns - 1];
  }
};
long long seg1[4 * MAX], seg2[4 * MAX];
matrix<int> lazy[4 * MAX];
int arr[MAX];
matrix<int> identity(2, 2, MOD);
inline pair<long long, long long> calc(long long a, long long b,
                                       matrix<int> &mat) {
  matrix<int> fib(2, 1, MOD);
  fib.grid[0][0] = a;
  fib.grid[1][0] = b;
  matrix<int> ret = (mat * fib);
  return make_pair(ret.grid[0][0], ret.grid[1][0]);
}
inline void build(int s, int e, int p, matrix<int> &mat) {
  assert(s <= e);
  lazy[p] = identity;
  if (s == e) {
    matrix<int> x = mat.power(arr[s]);
    pair<long long, long long> temp = calc(0, 1, x);
    seg1[p] = temp.first;
    seg2[p] = temp.second;
    return;
  }
  int mid = (s + e) >> 1;
  int l = p << 1;
  int r = l | 1;
  build(s, mid, l, mat);
  build(mid + 1, e, r, mat);
  seg1[p] = (seg1[l] + seg1[r]) >= MOD ? (seg1[l] + seg1[r] - MOD)
                                       : (seg1[l] + seg1[r]);
  seg2[p] = (seg2[l] + seg2[r]) >= MOD ? (seg2[l] + seg2[r] - MOD)
                                       : (seg2[l] + seg2[r]);
}
inline void relax(int p) {
  if (lazy[p / 2].grid[0][0] != 1 || lazy[p / 2].grid[1][1] != 1 ||
      lazy[p / 2].grid[0][1] + lazy[p / 2].grid[1][0] != 0) {
    int a = seg1[p];
    int b = seg2[p];
    matrix<int> &x = lazy[p / 2];
    pair<long long, long long> temp = calc(a, b, x);
    seg1[p] = temp.first;
    seg2[p] = temp.second;
    lazy[p] = lazy[p] * x;
  }
}
inline void update(int s, int e, int p, int us, int ue, matrix<int> &x) {
  assert(s <= e);
  relax(p);
  if (s > ue || us > e) return;
  if (us <= s && e <= ue) {
    int a = seg1[p];
    int b = seg2[p];
    pair<long long, long long> temp = calc(a, b, x);
    seg1[p] = temp.first;
    seg2[p] = temp.second;
    lazy[p] = lazy[p] * x;
    return;
  }
  int mid = (s + e) >> 1;
  int l = p << 1;
  int r = l | 1;
  update(s, mid, l, us, ue, x);
  update(mid + 1, e, r, us, ue, x);
  lazy[p] = identity;
  seg1[p] = (seg1[l] + seg1[r]) >= MOD ? (seg1[l] + seg1[r] - MOD)
                                       : (seg1[l] + seg1[r]);
  seg2[p] = (seg2[l] + seg2[r]) >= MOD ? (seg2[l] + seg2[r] - MOD)
                                       : (seg2[l] + seg2[r]);
}
inline int query(int s, int e, int p, int qs, int qe) {
  assert(s <= e);
  relax(p);
  if (s > qe || qs > e) return 0;
  if (qs <= s && e <= qe) return seg1[p];
  int mid = (s + e) >> 1;
  int l = p << 1;
  int r = l | 1;
  long long ret = (query(s, mid, l, qs, qe) + query(mid + 1, e, r, qs, qe));
  ret = (ret >= MOD) ? ret - MOD : ret;
  lazy[p] = identity;
  seg1[p] = (seg1[l] + seg1[r]) >= MOD ? (seg1[l] + seg1[r] - MOD)
                                       : (seg1[l] + seg1[r]);
  seg2[p] = (seg2[l] + seg2[r]) >= MOD ? (seg2[l] + seg2[r] - MOD)
                                       : (seg2[l] + seg2[r]);
  return ret;
}
int main() {
  identity.grid[0][0] = 1;
  identity.grid[1][1] = 1;
  matrix<int> def(2, 2, MOD);
  def.grid[0][0] = 0;
  def.grid[0][1] = 1;
  def.grid[1][0] = 1;
  def.grid[1][1] = 1;
  int n, m;
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= n; i++) scanf("%d", &arr[i]);
  build(1, n, 1, def);
  lazy[0] = identity;
  while (m--) {
    int t, s, e;
    scanf("%d %d %d", &t, &s, &e);
    if (t == 1) {
      int x;
      scanf("%d", &x);
      matrix<int> mat = def;
      mat = mat.power(x);
      update(1, n, 1, s, e, mat);
    } else
      printf("%d\n", query(1, n, 1, s, e));
  }
  return 0;
}
