#include <bits/stdc++.h>
using namespace std;
const int M = 1e9 + 7;
const int MAX = (1 << 17);
const int N = 2 * MAX + 7;
int n, m;
pair<int, int> tree[N];
pair<pair<int, int>, pair<int, int> > lazy[N], J = {{1, 1}, {1, 0}},
                                               E = {{0, 0}, {0, 0}};
inline pair<int, int> sum(pair<int, int> x, pair<int, int> y) {
  pair<int, int> res = {x.first + y.first, x.second + y.second};
  if (res.first >= M) res.first -= M;
  if (res.second >= M) res.second -= M;
  return res;
}
inline pair<int, int> mul(pair<int, int> x,
                          pair<pair<int, int>, pair<int, int> > y) {
  pair<int, int> res;
  res.first = ((long long)x.first * y.first.first +
               (long long)x.second * y.second.first) %
              M;
  res.second = ((long long)x.first * y.first.second +
                (long long)x.second * y.second.second) %
               M;
  return res;
}
inline pair<pair<int, int>, pair<int, int> > mul2(
    pair<pair<int, int>, pair<int, int> > x,
    pair<pair<int, int>, pair<int, int> > y) {
  pair<pair<int, int>, pair<int, int> > res;
  if (x == E) return y;
  res.first.first = ((long long)x.first.first * y.first.first +
                     (long long)x.first.second * y.second.first) %
                    M;
  res.first.second = ((long long)x.first.first * y.first.second +
                      (long long)x.first.second * y.second.second) %
                     M;
  res.second.first = ((long long)x.second.first * y.first.first +
                      (long long)x.second.second * y.second.first) %
                     M;
  res.second.second = ((long long)x.second.first * y.first.second +
                       (long long)x.second.second * y.second.second) %
                      M;
  return res;
}
inline pair<pair<int, int>, pair<int, int> > Power(int x) {
  x--;
  pair<pair<int, int>, pair<int, int> > res, a = res = J;
  while (x > 0) {
    if (x & 1) res = mul2(res, a);
    a = mul2(a, a);
    x >>= 1;
  }
  return res;
}
inline void propagate(int node, int i, int j) {
  if (lazy[node] == E) return;
  tree[node] = mul(tree[node], lazy[node]);
  if (i != j) {
    lazy[2 * node] = mul2(lazy[2 * node], lazy[node]);
    lazy[2 * node + 1] = mul2(lazy[2 * node + 1], lazy[node]);
  }
  lazy[node] = E;
}
inline void update(int a, int b, pair<pair<int, int>, pair<int, int> > v,
                   int node = 1, int i = 0, int j = MAX - 1) {
  propagate(node, i, j);
  if (b < i || j < a) return;
  if (a <= i && j <= b) {
    tree[node] = mul(tree[node], v);
    if (i != j) {
      lazy[2 * node] = mul2(lazy[2 * node], v);
      lazy[2 * node + 1] = mul2(lazy[2 * node + 1], v);
    }
    return;
  }
  update(a, b, v, 2 * node, i, (i + j) / 2);
  update(a, b, v, 2 * node + 1, (i + j) / 2 + 1, j);
  tree[node] = sum(tree[2 * node], tree[2 * node + 1]);
}
inline pair<int, int> query(int a, int b, int node = 1, int i = 0,
                            int j = MAX - 1) {
  propagate(node, i, j);
  if (b < i || j < a) return {0, 0};
  if (a <= i && j <= b) return tree[node];
  pair<int, int> l = query(a, b, 2 * node, i, (i + j) / 2),
                 r = query(a, b, 2 * node + 1, (i + j) / 2 + 1, j);
  return sum(l, r);
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) {
    int x;
    scanf("%d", &x);
    pair<pair<int, int>, pair<int, int> > a = Power(x);
    tree[i + MAX] = a.first;
  }
  for (int i = MAX - 1; i; i--) tree[i] = sum(tree[2 * i], tree[2 * i + 1]);
  while (m--) {
    int t, a, b;
    scanf("%d%d%d", &t, &a, &b);
    if (t == 2) {
      printf("%d\n", query(a, b).second);
    } else {
      int x;
      scanf("%d", &x);
      pair<pair<int, int>, pair<int, int> > r = Power(x);
      update(a, b, r);
    }
  }
  return 0;
}
