#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
using ll = long long;
using pii = pair<int, int>;
const int MOD = 1e9 + 7;
const ll INF = 5e9 + 1e2;
void fin() {}
const bool flag = 0;
const int N = 1e5 + 10;
int add(int a, int b) {
  a += b;
  if (a >= MOD) a -= MOD;
  return a;
}
int mult(int a, int b) { return a * 1ll * b % MOD; }
struct matrix {
  int n, m;
  int a[2][2];
  matrix(int n = 0, int m = 0, int val = 0) : n(n), m(m) {
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < m; ++j) {
        a[i][j] = val;
      }
    }
  }
  matrix operator*(matrix b) {
    if (this->empty()) {
      return b;
    }
    if (b.empty()) {
      return *this;
    }
    matrix c(n, b.m);
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < b.m; ++j) {
        for (int k = 0; k < m; ++k) {
          c.a[i][j] = add(c.a[i][j], mult(a[i][k], b.a[k][j]));
        }
      }
    }
    return c;
  }
  matrix binpow(int b) {
    matrix res(2, 2, 1);
    res.a[0][1] = res.a[1][0] = 0;
    auto th = *this;
    while (b) {
      if (b & 1) {
        res = res * th;
      }
      th = th * th;
      b >>= 1;
    }
    return res;
  }
  bool empty() { return (!n || !m); }
};
matrix operator+(matrix first, matrix second) {
  for (int i = 0; i < first.n; ++i) {
    for (int j = 0; j < first.m; ++j) {
      second.a[i][j] = add(second.a[i][j], first.a[i][j]);
    }
  }
  return second;
}
int a[N], n;
matrix t[N << 2], tag[N << 2], base;
void build(int u = 0, int l = 0, int r = n) {
  if (r - l == 1) {
    matrix empty(1, 2, 1);
    empty.a[0][0] = 0;
    t[u] = (empty * base.binpow(a[l] - 1));
    return;
  }
  int m = l + r >> 1;
  build(u + u + 1, l, m);
  build(u + u + 2, m, r);
  t[u] = t[u + u + 1] + t[u + u + 2];
}
void push(int u, int l, int r) {
  if (tag[u].empty() || r - l == 1) {
    return;
  }
  t[u + u + 1] = t[u + u + 1] * tag[u];
  t[u + u + 2] = t[u + u + 2] * tag[u];
  tag[u + u + 1] = tag[u + u + 1] * tag[u];
  tag[u + u + 2] = tag[u + u + 2] * tag[u];
  tag[u] = matrix();
}
void modify(int l, int r, matrix first, int u = 0, int ul = 0, int ur = n) {
  push(u, ul, ur);
  if (l >= ur || ul >= r) return;
  if (l <= ul && ur <= r) {
    t[u] = t[u] * first;
    tag[u] = first;
    return;
  }
  int um = ul + ur >> 1;
  modify(l, r, first, u + u + 1, ul, um);
  modify(l, r, first, u + u + 2, um, ur);
  t[u] = t[u + u + 1] + t[u + u + 2];
}
int get(int l, int r, int u = 0, int ul = 0, int ur = n) {
  push(u, ul, ur);
  if (l >= ur || ul >= r) return 0;
  if (l <= ul && ur <= r) return t[u].a[0][1];
  int um = ul + ur >> 1;
  return add(get(l, r, u + u + 1, ul, um), get(l, r, u + u + 2, um, ur));
}
void show(int u = 0, int l = 0, int r = n) {
  if (r - l == 1) {
    cout << t[u].a[0][1] << " ";
    return;
  }
  int m = l + r >> 1;
  show(u + u + 1, l, m);
  show(u + u + 2, m, r);
  t[u] = t[u + u + 1] + t[u + u + 2];
}
void ma1n() {
  int q;
  cin >> n >> q;
  for (int i = 0; i < n; ++i) cin >> a[i];
  base = matrix(2, 2, 1);
  base.a[0][0] = 0;
  build();
  for (int tp, l, r; q--;) {
    cin >> tp >> l >> r, l--;
    if (tp == 1) {
      int first;
      cin >> first;
      modify(l, r, base.binpow(first));
    } else {
      cout << get(l, r) << "\n";
    }
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(nullptr), fin();
  int ts = 1;
  if (flag) {
    cin >> ts;
  }
  while (ts--) {
    ma1n();
  }
  return 0;
}
