#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1000000007;
const int N = 100005;
int n, m, l, r, x, t;
int ql, qr;
long long a[N];
pair<long long, long long> b[N];
long long fibMat[64][2][2];
pair<long long, long long> seg_tree[N << 2];
long long lazy[N << 3];
inline void push(int id) {
  long long ans = seg_tree[id].first, ans1 = seg_tree[id].second, x, x1;
  long long num = lazy[id];
  for (int i = 0; i < 64; i++) {
    if (num & (1LL << i)) {
      x = ans, x1 = ans1;
      ans1 = (fibMat[i][0][0] * x1 + fibMat[i][0][1] * x) % MOD;
      ans = (fibMat[i][1][0] * x1 + fibMat[i][1][1] * x) % MOD;
    }
  }
  seg_tree[id] = {ans, ans1};
  lazy[id << 1] += num, lazy[id << 1 | 1] += num;
  lazy[id] = 0;
}
inline void build(int id = 1, int l = 0, int r = n) {
  if (r - l < 2) {
    seg_tree[id] = b[l];
    return;
  }
  int mid = (l + r) >> 1;
  build(id << 1, l, mid);
  build(id << 1 | 1, mid, r);
  seg_tree[id].first =
      (seg_tree[id << 1].first + seg_tree[id << 1 | 1].first) % MOD;
  seg_tree[id].second =
      (seg_tree[id << 1].second + seg_tree[id << 1 | 1].second) % MOD;
}
inline void modify(int val, int id = 1, int l = 0, int r = n) {
  if (lazy[id]) push(id);
  if (ql >= r || l >= qr) return;
  if (ql <= l && r <= qr) {
    lazy[id] += val;
    push(id);
    return;
  }
  int mid = (l + r) >> 1;
  modify(val, id << 1, l, mid);
  modify(val, id << 1 | 1, mid, r);
  seg_tree[id].first =
      (seg_tree[id << 1].first + seg_tree[id << 1 | 1].first) % MOD;
  seg_tree[id].second =
      (seg_tree[id << 1].second + seg_tree[id << 1 | 1].second) % MOD;
}
inline long long query(int id = 1, int l = 0, int r = n) {
  if (lazy[id]) push(id);
  if (ql >= r || l >= qr) return 0;
  if (ql <= l && r <= qr) return seg_tree[id].first;
  int mid = (l + r) >> 1;
  return (query(id << 1, l, mid) + query(id << 1 | 1, mid, r)) % MOD;
}
void pre() {
  fibMat[0][0][1] = fibMat[0][1][1] = fibMat[0][1][0] = 1LL;
  for (int x = 1; x < 64; x++) {
    for (int i = 0; i < 2; i++)
      for (int j = 0; j < 2; j++) {
        for (int k = 0; k < 2; k++)
          fibMat[x][i][j] += (fibMat[x - 1][i][k] * fibMat[x - 1][k][j]) % MOD;
        fibMat[x][i][j] %= MOD;
      }
  }
}
inline pair<long long, long long> getFib(long long num) {
  long long ans = 1, ans1 = 0, x, x1;
  num--;
  for (int i = 0; i < 64; i++) {
    if (num & (1LL << i)) {
      x = ans, x1 = ans1;
      ans1 = (fibMat[i][0][0] * x1 + fibMat[i][0][1] * x) % MOD;
      ans = (fibMat[i][1][0] * x1 + fibMat[i][1][1] * x) % MOD;
    }
  }
  return {ans, ans1};
}
int main() {
  pre();
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; i++) {
    scanf("%lld", a + i);
    b[i] = getFib(a[i]);
  }
  build();
  while (m--) {
    scanf("%d %d %d", &t, &l, &r);
    ql = --l, qr = r;
    if (t == 1) {
      scanf("%d", &x);
      modify(x);
    } else {
      printf("%lld\n", (query() + MOD) % MOD);
    }
  }
  return 0;
}
