#include <bits/stdc++.h>
using namespace std;
const int maxn = 100009;
const int mod = 1e9 + 7;
struct Matrix {
  int a[2][2];
  Matrix() { memset(a, 0, sizeof a); }
  void init() {
    memset(a, 0, sizeof a);
    for (int i = 0; i < 2; i++) a[i][i] = 1;
  }
  Matrix operator+(const Matrix &x) {
    Matrix c;
    c.a[0][0] = (x.a[0][0] + a[0][0]) % mod;
    c.a[0][1] = (x.a[0][1] + a[0][1]) % mod;
    c.a[1][0] = (x.a[1][0] + a[1][0]) % mod;
    c.a[1][1] = (x.a[1][1] + a[1][1]) % mod;
    return c;
  }
  Matrix operator*(const Matrix &x) {
    Matrix c;
    c.a[0][0] = (1LL * x.a[0][0] * a[0][0] + 1LL * x.a[0][1] * a[1][0]) % mod;
    c.a[0][1] = (1LL * x.a[0][0] * a[0][1] + 1LL * x.a[0][1] * a[1][1]) % mod;
    c.a[1][0] = (1LL * x.a[1][0] * a[0][0] + 1LL * x.a[1][1] * a[1][0]) % mod;
    c.a[1][1] = (1LL * x.a[1][0] * a[0][1] + 1LL * x.a[1][1] * a[1][1]) % mod;
    return c;
  }
} zero, one, table, tmp;
inline Matrix PowerMod(Matrix x, long long y) {
  if (y < 0) return zero;
  Matrix ans = one;
  while (y) {
    if (y & 1) ans = ans * x;
    x = x * x;
    y >>= 1;
  }
  return ans;
}
struct sg_tree {
  Matrix now;
  Matrix tag;
} node[maxn << 2];
int n, m;
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
inline void updata(int rt) {
  node[rt].now = node[rt << 1].now + node[rt << 1 | 1].now;
}
void build(int l, int r, int rt) {
  node[rt].tag.init();
  if (l == r) {
    int x = read();
    node[rt].now = PowerMod(table, x);
    return;
  }
  int mid = (l + r) >> 1;
  build(l, mid, rt << 1);
  build(mid + 1, r, rt << 1 | 1);
  updata(rt);
}
inline void down(int rt) {
  node[rt << 1].now = node[rt << 1].now * node[rt].tag;
  node[rt << 1].tag = node[rt << 1].tag * node[rt].tag;
  node[rt << 1 | 1].now = node[rt << 1 | 1].now * node[rt].tag;
  node[rt << 1 | 1].tag = node[rt << 1 | 1].tag * node[rt].tag;
  node[rt].tag.init();
}
void modify(int l, int r, int rt, int left, int right) {
  if (l == left && right == r) {
    node[rt].now = node[rt].now * tmp;
    node[rt].tag = node[rt].tag * tmp;
    return;
  }
  down(rt);
  int mid = (l + r) >> 1;
  if (right <= mid)
    modify(l, mid, rt << 1, left, right);
  else if (left > mid)
    modify(mid + 1, r, rt << 1 | 1, left, right);
  else
    modify(l, mid, rt << 1, left, mid),
        modify(mid + 1, r, rt << 1 | 1, mid + 1, right);
  updata(rt);
}
int query(int l, int r, int rt, int left, int right) {
  if (left <= l && r <= right) return node[rt].now.a[1][0];
  int mid = (l + r) >> 1;
  down(rt);
  if (right <= mid)
    return query(l, mid, rt << 1, left, right);
  else if (left > mid)
    return query(mid + 1, r, rt << 1 | 1, left, right);
  else
    return (query(l, mid, rt << 1, left, mid) +
            query(mid + 1, r, rt << 1 | 1, mid + 1, right)) %
           mod;
}
char buff[30];
inline void write(int x) {
  int bit = 0;
  while (x) {
    buff[++bit] = x % 10;
    x /= 10;
  }
  for (int i = bit; i >= 1; i--) putchar(buff[i] + '0');
}
int main() {
  n = read();
  m = read();
  one.init();
  table.a[0][1] = table.a[1][0] = table.a[1][1] = 1;
  build(1, n, 1);
  while (m--) {
    int opt = read(), l = read(), r = read();
    if (opt == 1) {
      int x = read();
      tmp = PowerMod(table, x);
      modify(1, n, 1, l, r);
    } else
      write(query(1, n, 1, l, r)), puts("");
  }
  return 0;
}
