#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#define MogeKo qwq
using namespace std;
#define ls (now<<1)
#define rs (now<<1|1)
const int maxn = 1e6+10;
const int mod = 1e9+9;

int n,m,x,y,op;
long long a[maxn],f[maxn];

struct tree {
	long long sum,c1,c2;
} t[maxn];

int read() {
	int x = 0,f = 1;
	char ch = getchar();
	while(ch < '0' || ch > '9') {
		if(ch == '-') f = -1;
		ch = getchar();
	}
	while('0' <= ch && ch <= '9') {
		x = (x<<3)+(x<<1) + ch-'0';
		ch = getchar();
	}
	return x * f;
}

long long getx(long long a1,long long a2,long long x) {
	if(x == 1) return a1;
	if(x == 2) return a2;
	return ( a1*f[x-2] + a2*f[x-1] ) % mod;
}

long long getsum(long long a1,long long a2,long long x) {
	if(x == 1) return a1;
	if(x == 2) return (a1+a2) % mod;
	return ( getx(a1,a2,x+2) - a2 + mod ) % mod;
}

void pushup(int now) {
	t[now].sum = (t[ls].sum + t[rs].sum) % mod;
}

void pushdown(int l,int r,int now) {
	if(!t[now].c1) return;
	int mid = (l+r)>>1;
	long long a1,a2;
	a1 = t[now].c1;
	a2 = t[now].c2;
	t[ls].c1 = (t[ls].c1 + a1) % mod;
	t[ls].c2 = (t[ls].c2 + a2) % mod;
	t[ls].sum = (t[ls].sum + getsum(a1,a2,mid-l+1)) % mod;
	a1 = getx(t[now].c1,t[now].c2,mid-l+2);
	a2 = getx(t[now].c1,t[now].c2,mid-l+3);
	t[rs].c1 = (t[rs].c1 + a1) % mod;
	t[rs].c2 = (t[rs].c2 + a2) % mod;
	t[rs].sum = (t[rs].sum + getsum(a1,a2,r-mid)) % mod;
	t[now].c1 = t[now].c2 = 0;
}

void modify(int L,int R,int l,int r,int now) {
	if(L <= l && r <= R) {
		t[now].c1 = (t[now].c1 + f[l-L+1]) % mod;
		t[now].c2 = (t[now].c2 + f[l-L+2]) % mod;
		t[now].sum = (t[now].sum + getsum(f[l-L+1],f[l-L+2],r-l+1)) % mod;
		return;
	}
	pushdown(l,r,now);
	int mid = (l+r)>>1;
	if(L <= mid) modify(L,R,l,mid,ls);
	if(R > mid) modify(L,R,mid+1,r,rs);
	pushup(now);
}

long long query(int L,int R,int l,int r,int now) {
	long long ans = 0;
	if(L <= l && r <= R) {
		ans = t[now].sum;
		return (ans + mod) % mod;
	}
	pushdown(l,r,now);
	int mid = (l+r)>>1;
	if(L <= mid) ans += query(L,R,l,mid,ls);
	if(R > mid) ans += query(L,R,mid+1,r,rs);
	return (ans+mod)%mod;
}

void init() {
	f[1] = f[2] = 1;
	for(int i = 3; i <= n+2; i++)
		f[i] = (f[i-1] + f[i-2]) %mod;
}

int main() {
	n = read(),m = read();
	for(int i = 1; i <= n; i++) {
		x = read();
		a[i] = (a[i-1] + x) % mod;
	}
	init();
	while(m--) {
		op = read();
		x = read(), y = read();
		if(op == 1) modify(x,y,1,n,1);
		if(op == 2) printf("%lld\n",(a[y]-a[x-1]+query(x,y,1,n,1)+mod)%mod);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
#define drep(i, a, b) for(int i = (a), i##_end_ = (b); i >= i##_end_; --i)
#define clar(a, b) memset((a), (b), sizeof(a))
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define Debug(s) debug("The massage in line %d, Function %s: %s\n", __LINE__, __FUNCTION__, s)
typedef long long LL;
typedef long double LD;
int read() {
    char ch = getchar();
    int x = 0, flag = 1;
    for(;!isdigit(ch); ch = getchar()) if(ch == '-') flag *= -1;
    for(;isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
    return x * flag;
}
void write(int x) {
    if(x < 0) putchar('-'), x = -x;
    if(x >= 10) write(x / 10);
    putchar(x % 10 + 48);
}

#define Maxn 300009
const LL Mod = (LL)(1e9 + 9);
int n, a[Maxn], m; LL f[Maxn];
struct node { LL x, y; };
LL FibDelta(LL F1, LL F2, LL len) {
    LL res = 0;
    if(len >= 1) (res += F1) %= Mod;
    if(len >= 2) (res += F2) %= Mod;
    if(len >= 3) (res += (F2 * (f[len + 1] - 2ll) % Mod + F1 * (f[len] - 1ll) % Mod) % Mod) %= Mod;
    return res;
}// needs to be analyzed in different conditions
node FibForward(node s, int len) {
    LL c = s.x * f[len] % Mod + s.y * f[len + 1] % Mod, d = s.x * f[len + 1] % Mod + s.y * f[len + 2] % Mod;
    return (node){c % Mod, d % Mod};
}
namespace SGMT_tree {
    LL tree[Maxn << 2], beg[Maxn << 2][2], val[Maxn << 2];
#define lc(x) (x) << 1
#define rc(x) (x) << 1 | 1
#define ls rt << 1, l, mid
#define rs rt << 1 | 1, mid + 1, r
    void pushup(int rt) { tree[rt] = (1ll * tree[lc(rt)] + 1ll * tree[rc(rt)]) % Mod; }
    void pushdown(int rt, int l, int r) {
        int mid = (l + r) >> 1;
        if(val[rt]) {
            LL &a = beg[rt][0], &b = beg[rt][1];
            (beg[lc(rt)][0] += a) %= Mod, (beg[lc(rt)][1] += b) %= Mod;
            (tree[lc(rt)] += FibDelta(a, b, mid - l + 1)) %= Mod;
            val[lc(rt)] = 1;

            LL c = a * f[mid - l] + b * f[mid - l + 1], d = a * f[mid - l + 1] + b * f[mid - l + 2];
            c %= Mod, d %= Mod;
            (beg[rc(rt)][0] += c) %= Mod, (beg[rc(rt)][1] += d) %= Mod;
            (tree[rc(rt)] += FibDelta(c, d, r - mid)) %= Mod;
            val[rc(rt)] = 1;
            beg[rt][0] = beg[rt][1] = 0;
            val[rt] = 0;
        }
    }
    void build(int rt, int l, int r) {
        if(l == r) {
            tree[rt] = a[l];
            return ;
        }
        int mid = (l + r) >> 1;
        build(ls), build(rs);
        pushup(rt);
    }
    void modify(int rt, int l, int r, int x, int y, int p1, int p2) {
        if(x <= l && r <= y) {
            (beg[rt][0] += p1) %= Mod, (beg[rt][1] += p2) %= Mod;
            (tree[rt] += FibDelta(p1, p2, r - l + 1)) %= Mod;
            val[rt] = 1;
            return ;
        }

        int mid = (l + r) >> 1;
        pushdown(rt, l, r);

        if(y <= mid)  modify(ls, x, y, p1, p2);
        else if(mid + 1 <= x)  modify(rs, x, y, p1, p2);
        else {
            modify(ls, x, mid, p1, p2); /**/
            node z = FibForward((node){p1, p2}, mid - x);/**/
            //F[i] -> F[i + mid - x]: p1 -> z.x, p2 -> z.y
            modify(rs, mid + 1, y, z.x, z.y);/*The InterVal's Range needs to be moved*/
        }
        pushup(rt);
    }
    int query(int rt, int l, int r, int x, int y) {
        if(x <= l && r <= y) return tree[rt];

        int mid = (l + r) >> 1; pushdown(rt, l, r);

        if(y <= mid) return query(ls, x, y);
        else if(mid + 1 <= x) return query(rs, x, y);
        else return (1ll * query(ls, x, y) + 1ll * query(rs, x, y)) % Mod;
    }
#undef lc
#undef rc
#undef ls
#undef rs
}
namespace INIT {
    void Main() {
        n = read(), m = read();

        f[1] = 1; f[2] = 1;
        rep(i, 3, n + 4) f[i] = (f[i - 1] * 1ll + f[i - 2]) % Mod;

        rep(i, 1, n) a[i] = read() % Mod;

        SGMT_tree :: build(1, 1, n);
    }
}
namespace SOLVE {
    void Main() {
        rep(i, 1, m) {
            int opt = read();

            if(opt == 1) {
                int x = read(), y = read();
                SGMT_tree :: modify(1, 1, n, x, y, 1, 1);
            }
            if(opt == 2) {
                int x = read(), y = read();
                write(SGMT_tree :: query(1, 1, n, x, y) % Mod), putchar('\n');
            }
        }
    }
}
int main() {

    INIT :: Main();
    SOLVE :: Main();
#ifdef Qrsikno
    debug("\nRunning time: %.3lf(s)\n", clock() * 1.0 / CLOCKS_PER_SEC);
#endif
    return 0;
}


#include<bits/stdc++.h>
#define int long long
using namespace std;
int read(){
    int c=0,nx,sign=1;
    do{
        nx=getchar()-'0';
        if(nx=='-'-'0')
            sign=-1;
    }while(nx<0 or nx>9);
    while(nx>=0 and nx<=9){
        c=c*10+nx;
        nx=getchar()-'0';
    }
    return sign*c;
}
const int N=5e5+10,mod=1e9+7;
int fib[2*N],a[N];
struct stree{
    int tot,a,b;
    stree *ls,*rs;
}c[4*N];
stree* New(){
    static int now=0;
    stree &s=c[++now];
    s.tot=s.a=s.b=0;
    s.ls=s.rs=c;
    return c+now;
}
inline int h(int a,int b,int x){
    if(x>=2)
        return (a*fib[x-2] + b*fib[x-1]) % mod;
    else
        return a;
}
inline void pd(stree &s,int a,int b,int l,int r){
    s.a = (s.a + a) % mod;
    s.b = (s.b + b) % mod;
    s.tot = (s.tot + h(a,b,r-l+3) - b + mod) % mod;
}
void pushdown(stree &s,int l,int r){
    if(!s.a and !s.b or l==r)
        return ;
    int mid=(l+r)>>1;
    int &a=s.a,&b=s.b;
    pd(*s.ls,a,b,l,mid);
    pd(*s.rs,h(a,b,mid+2-l),h(a,b,mid+3-l),mid+1,r);
    a=b=0;
}
inline void pushup(stree &s){
    s.tot = (s.ls->tot + s.rs->tot) % mod;
}
void add(int ql,int qr,stree &s,int l,int r){
    if(ql<=l and r<=qr){
        pd(s,fib[l-ql+1],fib[l-ql+2],l,r);
        return ;
    }
    pushdown(s,l,r);
    int mid=(l+r)>>1;
    if(ql<=mid)
        add(ql,qr,*s.ls,l,mid);
    if(qr>mid)
        add(ql,qr,*s.rs,mid+1,r);
    pushup(s);
}
int query(int ql,int qr,stree &s,int l,int r){
    if(ql<=l and r<=qr){
        return s.tot;
    }
    pushdown(s,l,r);
    int mid=(l+r)>>1,ans=0;
    if(ql<=mid)
        ans+=query(ql,qr,*s.ls,l,mid);
    if(qr>mid)
        ans+=query(ql,qr,*s.rs,mid+1,r);
    return ans % mod;
}
void build(stree &s,int l,int r){
    if(l==r){
        s.tot=a[l];
        return ;
    }
    s.ls = New();
    s.rs = New();
    int mid = (l + r) >> 1;
    build(*s.ls,l,mid);
    build(*s.rs,mid+1,r);
    pushup(s);
}

signed main(){
    fib[1]=1;
    for(int i=2;i<=2e6;i++)
        fib[i]=(fib[i-1] + fib[i-2]) % mod;

    int n=read(),t=read();
    for(int i=1;i<=n;i++)
        a[i]=read();

    stree &root=*New();
    build(root,1,n);

    while(t--){
        int ord=read(),l=read(),r=read();
        switch(ord){
            case 1:
                add(l,r,root,1,n);
                break;
            case 2:
                printf("%lld\n",query(l,r,root,1,n));
                break;
        }
    }
}


#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define ls p<<1
#define rs p<<1|1
using namespace std;
typedef long long ll;
const int mxn=1e6+5,mod=1e9+9;
int n,m,cnt,a[mxn],hd[mxn];
ll f[mxn],tr[mxn<<2],vis[mxn<<2],tag[mxn<<2][2];

inline int read() {
	char c=getchar(); int x=0,f=1;
	while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
	while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}
	return x*f;
}
inline void chkmax(int &x,int y) {if(x<y) x=y;}
inline void chkmin(int &x,int y) {if(x>y) x=y;}

struct ed {
	int to,nxt;
}t[mxn<<1];

inline void add(int u,int v) {
	t[++cnt]=(ed) {v,hd[u]}; hd[u]=cnt;
}

void push_up(int p) {
	tr[p]=(tr[ls]+tr[rs])%mod;
}

struct ST {
	ll x,y;
};

ST fibget(ST tp,int len) {
	ll c=tp.x*f[len]%mod+tp.y*f[len+1]%mod,d=tp.x*f[len+1]%mod+tp.y*f[len+2]%mod;
	return (ST) {c%mod,d%mod};
}

ll fibcal(ll f1,ll f2,ll len) {
	ll res=0;
	if(len>=1) res=f1;
	if(len>=2) res=(res+f2)%mod;
	if(len>=3) res=(res+f2*(f[len+1]-2)%mod+f1*(f[len]-1)%mod+mod)%mod;
	//前两项的系数的值,直接乘以当前f[i+1],f[i],计算出f[i+2]
	return res;
}

void push_down(int p,int l,int r) {
	int mid=(l+r)>>1;
	if(vis[p]) {
		ll &a=tag[p][0],&b=tag[p][1];
		tag[ls][0]=(tag[ls][0]+a)%mod;
		tag[ls][1]=(tag[ls][1]+b)%mod;
		tr[ls]=(tr[ls]+fibcal(a,b,mid-l+1))%mod;
		vis[ls]=1;

		ll c=a*f[mid-l]+b*f[mid-l+1],d=a*f[mid-l+1]+b*f[mid-l+2];
		c%=mod; d%=mod;
		tag[rs][0]=(tag[rs][0]+c)%mod;
		tag[rs][1]=(tag[rs][1]+d)%mod;
		tr[rs]=(tr[rs]+fibcal(c,d,r-mid))%mod;
		vis[rs]=1;

		vis[p]=tag[p][0]=tag[p][1]=0;
	}
}

void build(int l,int r,int p) {
	if(l==r) {tr[p]=a[l]; return ;}
	int mid=(l+r)>>1;
	build(l,mid,ls); build(mid+1,r,rs); push_up(p);
}

void modify(int l,int r,int ql,int qr,int val1,int val2,int p) {
	if(ql<=l&&r<=qr) {
		tag[p][0]=(tag[p][0]+val1)%mod;
		tag[p][1]=(tag[p][1]+val2)%mod;
		tr[p]=(tr[p]+fibcal(val1,val2,r-l+1))%mod;
		vis[p]=1; return ;
	}
	int mid=(l+r)>>1; push_down(p,l,r);
	if(qr<=mid) modify(l,mid,ql,qr,val1,val2,ls);
	else if(ql>mid) modify(mid+1,r,ql,qr,val1,val2,rs);
	else {
		modify(l,mid,ql,qr,val1,val2,ls);
		ST z=fibget((ST){val1,val2},mid-ql);
		modify(mid+1,r,ql,qr,z.x,z.y,rs); //算出区间前两个fib,貌似也可以用前缀和
	}
	push_up(p);
}

int query(int l,int r,int ql,int qr,int p) {
	if(ql<=l&&r<=qr) return tr[p];
	int mid=(l+r)>>1; push_down(p,l,r); int res=0;
	if(ql<=mid) res=(res+query(l,mid,ql,qr,ls))%mod;
	if(qr>mid) res=(res+query(mid+1,r,ql,qr,rs))%mod;
	return res;
}

void init() {
	n=read(); m=read(); int x,y,opt; f[1]=f[2]=1;
	for(int i=3;i<=n+4;++i) f[i]=(f[i-1]+f[i-2])%mod;
	for(int i=1;i<=n;++i) a[i]=read()%mod; build(1,n,1);
	for(int i=1;i<=m;++i) {
		opt=read(); x=read(); y=read();
		if(opt==1) modify(1,n,x,y,1,1,1);
		else printf("%d\n",query(1,n,x,y,1));
	}
}

int main()
{
	init();
    return 0;
}


#include<bits/stdc++.h>
#define int long long
using namespace std;
int read(){
    int c=0,nx,sign=1;
    do{
        nx=getchar()-'0';
        if(nx=='-'-'0')
            sign=-1;
    }while(nx<0 or nx>9);
    while(nx>=0 and nx<=9){
        c=c*10+nx;
        nx=getchar()-'0';
    }
    return sign*c;
}
const int N=5e5+10,mod=1e9+9;
int fib[2*N],a[N];
struct stree{
    int tot,a,b;
    stree *ls,*rs;
}c[4*N];
stree* New(){
    static int now=0;
    stree &s=c[++now];
    s.tot=s.a=s.b=0;
    s.ls=s.rs=c;
    return c+now;
}
inline int h(int a,int b,int x){
    if(x>=2)
        return (a*fib[x-2] + b*fib[x-1]) % mod;
    else
        return a;
}
inline void pd(stree &s,int a,int b,int l,int r){
    s.a = (s.a + a) % mod;
    s.b = (s.b + b) % mod;
    s.tot = (s.tot + h(a,b,r-l+3) - b + mod) % mod;
}
void pushdown(stree &s,int l,int r){
    if(!s.a and !s.b or l==r)
        return ;
    int mid=(l+r)>>1;
    int &a=s.a,&b=s.b;
    pd(*s.ls,a,b,l,mid);
    pd(*s.rs,h(a,b,mid+2-l),h(a,b,mid+3-l),mid+1,r);
    a=b=0;
}
inline void pushup(stree &s){
    s.tot = (s.ls->tot + s.rs->tot) % mod;
}
void add(int ql,int qr,stree &s,int l,int r){
    if(ql<=l and r<=qr){
        pd(s,fib[l-ql+1],fib[l-ql+2],l,r);
        return ;
    }
    pushdown(s,l,r);
    int mid=(l+r)>>1;
    if(ql<=mid)
        add(ql,qr,*s.ls,l,mid);
    if(qr>mid)
        add(ql,qr,*s.rs,mid+1,r);
    pushup(s);
}
int query(int ql,int qr,stree &s,int l,int r){
    if(ql<=l and r<=qr){
        return s.tot;
    }
    pushdown(s,l,r);
    int mid=(l+r)>>1,ans=0;
    if(ql<=mid)
        ans+=query(ql,qr,*s.ls,l,mid);
    if(qr>mid)
        ans+=query(ql,qr,*s.rs,mid+1,r);
    return ans % mod;
}
void build(stree &s,int l,int r){
    if(l==r){
        s.tot=a[l];
        return ;
    }
    s.ls = New();
    s.rs = New();
    int mid = (l + r) >> 1;
    build(*s.ls,l,mid);
    build(*s.rs,mid+1,r);
    pushup(s);
}

signed main(){
    fib[1]=1;
    for(int i=2;i<=1e6;i++)
        fib[i]=(fib[i-1] + fib[i-2]) % mod;

    int n=read(),t=read();
    for(int i=1;i<=n;i++)
        a[i]=read();

    stree &root=*New();
    build(root,1,n);

    while(t--){
        int ord=read(),l=read(),r=read();
        switch(ord){
            case 1:
                add(l,r,root,1,n);
                break;
            case 2:
                printf("%lld\n",query(l,r,root,1,n));
                break;
        }
    }
}


#include <bits/stdc++.h>
using namespace std;

#define Int register int
#define mod 1000000007
#define ll long long
#define MAXN 300005

int read ()
{
	int x = 0;char c = getchar();int f = 1;
	while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}
	while (c >= '0' && c <= '9'){x = (x << 3) + (x << 1) + c - '0';c = getchar();}
	return x * f;
}

void write (int x)
{
	if (x < 0){x = -x;putchar ('-');}
	if (x > 9) write (x / 10);
	putchar (x % 10 + '0');
}

struct node
{
	int l,r,x,y,sum;//斐波拉契数列懒标记开头两项，以及区间和
}tree[MAXN << 2];

int n,m,F[MAXN];

void Init (int N)
{
	F[0] = 0,F[1] = 1;
	for (Int i = 2;i <= N + 3;++ i)
		F[i] = (F[i - 1] + F[i - 2]) % mod;
}

void Pushup (int i)
{
	tree[i].sum = (tree[i << 1].sum + tree[i << 1 | 1].sum) % mod;
}

int fib (int x,int y,int len)
{
	if (len == 1) return x;
	else if (len == 2) return y;
	else return ((ll)x * F[len - 2] % mod + (ll)y * F[len - 1] % mod) % mod;
}

int FibSum (int x,int y,int len)
{
	if (len == 1) return x;
	else if (len == 2) return (x + y) % mod;
	else return (fib (x,y,len + 2) + mod - y) % mod;
}

void Pushdown (int i)
{
	int l = tree[i].l,r = tree[i].r;
	if (tree[i].x)
	{
		int mid = (l + r) >> 1;
		tree[i << 1].x = (tree[i << 1].x + tree[i].x) % mod;
		tree[i << 1].y = (tree[i << 1].y + tree[i].y) % mod;
		tree[i << 1].sum = (tree[i << 1].sum + FibSum (tree[i].x,tree[i].y,mid - l + 1)) % mod;
		int x = fib (tree[i].x,tree[i].y,mid - l + 2),y = fib (tree[i].x,tree[i].y,mid - l + 3);
		tree[i << 1 | 1].x = (tree[i << 1 | 1].x + x) % mod;
		tree[i << 1 | 1].y = (tree[i << 1 | 1].y + y) % mod;
		tree[i << 1 | 1].sum = (tree[i << 1 | 1].sum + FibSum (x,y,r - mid)) % mod;
		tree[i].x = tree[i].y = 0;
	}
}

void build (int i,int l,int r)
{
	tree[i].l = l,tree[i].r = r;
	if (l == r) return tree[i].sum = read (),tree[i].x = tree[i].y = 0,void ();
	int mid = (l + r) >> 1;
	build (i << 1,l,mid);
	build (i << 1 | 1,mid + 1,r);
	Pushup (i);
}

void update (int i,int l,int r)
{
	if (tree[i].l > r || l > tree[i].r) return ;
	if (tree[i].l >= l && tree[i].r <= r)
	{
		tree[i].x = (tree[i].x + F[tree[i].l - l + 1]) % mod;
		tree[i].y = (tree[i].y + F[tree[i].l - l + 2]) % mod;
		tree[i].sum = (tree[i].sum + FibSum (F[tree[i].l - l + 1],F[tree[i].l - l + 2],tree[i].r - tree[i].l + 1)) % mod;
		return ;
	}
	Pushdown (i);
	update (i << 1,l,r);
	update (i << 1 | 1,l,r);
	Pushup (i);
}

int query (int i,int l,int r)
{
	if (tree[i].l > r || l > tree[i].r) return 0;
	if (tree[i].l >= l && tree[i].r <= r) return tree[i].sum;
	Pushdown (i);
	return (query (i << 1,l,r) + query (i << 1 | 1,l,r)) % mod;
}

signed main()
{
	n = read ();Init (n);m = read ();
	build (1,1,n);
	for (Int i = 1;i <= m;++ i)
	{
		int type = read (),l = read (),r = read ();
		if (type == 1) update (1,l,r);
		else write (query (1,l,r)),putchar ('\n');
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#define int long long
using namespace std;
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<<3)+(x<<1)+(ch^48);ch=getchar();}
	return x*f;
}
int n,m;
const int N = 310000;
const int mod = 1e9 + 9;
int tr[N << 2],tag[N << 2][2];
int f[N << 1];

void update(int k){tr[k] = (tr[k << 1] + tr[k << 1 | 1]) % mod;}

void down(int k,int l,int r)
{
	int mid = (l + r) >> 1;

	int x = (tag[k][0] * f[mid - l] % mod + tag[k][1] * f[mid - l + 1] % mod) % mod;
	int y = (tag[k][0] * f[mid - l + 1] % mod + tag[k][1] * f[mid - l + 2] % mod) % mod;

	tag[k << 1][0] = (tag[k << 1][0] + tag[k][0]) % mod;
	tag[k << 1 | 1][0] = (tag[k << 1 | 1][0] + x) % mod;

	tag[k << 1][1] = (tag[k << 1][1] + tag[k][1]) % mod;
	tag[k << 1 | 1][1] = (tag[k << 1 | 1][1] + y) % mod;

	tr[k << 1] = ((tr[k << 1] + tag[k][0] * f[mid - l + 1] % mod + tag[k][1] * f[mid - l + 2] % mod) % mod - tag[k][1] + mod) % mod;
	tr[k << 1 | 1] = ((tr[k << 1 | 1] + x * f[r - mid] + y * f[r - mid + 1]) % mod - y + mod) % mod;
	tag[k][0] = tag[k][1] = 0;
}

void change(int k,int l,int r,int x,int y,int v)
{
	if(x <= l && y >= r)
	{
		int len = r - l + 1;
		tag[k][0] = (tag[k][0] + f[l - x + v]) % mod;
		tag[k][1] = (tag[k][1] + f[l - x + v + 1]) % mod;
		tr[k] = ((tr[k] + f[l - x + v] * f[len] % mod + f[l - x + v + 1] * f[len + 1] % mod - f[l - x + v + 1]) % mod + mod) % mod;
		return;
	}
	int mid = (l + r) >> 1;
	if(tag[k][0] || tag[k][1]) down(k,l,r);
	if(x <= mid)	change(k << 1,l,mid,x,y,v);
	if(y > mid) 	change(k << 1 | 1,mid + 1,r,x,y,v);
	update(k);
	return;
}

int ask(int k,int l,int r,int x,int y)
{
	if(x <= l && y >= r) return tr[k];
	int mid = (l + r) >> 1,ans = 0;
	if(tag[k][0] || tag[k][1]) down(k,l,r);
	if(x <= mid) ans = (ans + ask(k << 1,l,mid,x,y)) % mod;
	if(y > mid)	 ans = (ans + ask(k << 1 | 1,mid + 1,r,x,y)) % mod;
	return ans;
}

void build(int k,int l,int r)
{
	if(l == r)
	{
		tr[k] = read();
		return;
	}
	int mid = (l + r) >> 1;
	build(k << 1,l,mid);
	build(k << 1 | 1,mid + 1,r);
	update(k);
}

signed main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	n = read();m = read();
	f[1] = f[2] = 1;
	for(int i = 3;i <= (n << 1);i ++) f[i] = (f[i - 1] + f[i - 2]) % mod;
	build(1,1,n);
	int opt,l,r,x = 1;
	while(m --)
	{
		opt = read();l = read();r = read();
		if(opt == 1)
		{
//			x = read();
			change(1,1,n,l,r,x);
		}
		else
		{
			printf("%lld\n",ask(1,1,n,l,r) % mod);
		}
	}
//	fclose(stdin);fclose(stdout);
	return 0;
}
/*
1049358504
1000000009
49358495
*/


#include<cstdio>
#include<iostream>
#define int long long
using namespace std;
const int mod = 1e9 + 7;
const int N = 300005;
int n,m;
long long f[N << 1],a[N],sum[N];
struct node{
	long long f1,f2,v;
	node(long long f1 = 0,long long f2 = 0,long long v = 0):f1(f1),f2(f2),v(v){};
}tr[N << 4];
void init()
{
	f[0] = 0;f[1] = 1;
	for(int i = 2;i <= 200000;i ++)	f[i] = (f[i - 1] + f[i - 2]) % mod;
}
void update(int k,int len)
{
	tr[k].f1 %= mod;	tr[k].f2 %= mod;
	tr[k].v = (((tr[k << 1].v + tr[k << 1 | 1].v) % mod + tr[k].f1 * f[len] % mod + tr[k].f2 * f[len + 1] % mod - tr[k].f2) % mod + mod) % mod;
//	cout << tr[k << 1].v << " " << tr[k << 1 | 1].v << endl;
}/*
void down(int k,int l,int r)
{
	cout << k << endl;
	if(tr[k].f1 == 0 && tr[k].f2 == 0)	return;
	int mid = (l + r) >> 1;
	tr[k << 1].f1 += tr[k].f1;	tr[k << 1].f2 += tr[k].f2;
	tr[k << 1 | 1].f1 += (tr[k].f1 * f[mid - l] % mod + tr[k].f2 * f[mid - l + 1] % mod) % mod;
	tr[k << 1 | 1].f2 += (tr[k].f1 * f[mid - l + 1] % mod + tr[k].f2 * f[mid - l + 2] % mod) % mod;
	tr[k].f1 = tr[k].f2 = 0;
//	cout << tr[k].f2 << " " << tr[k << 1 | 1].f2 << endl;
	update(k << 1,mid - l + 1);	update(k << 1 | 1,r - mid);
}*/
void down(int rt,int l,int r)
{
    if(tr[rt].f1==0&&tr[rt].f2==0)return ;
    int mid=(l+r)>>1;	int ls = (rt << 1),rs = (rt << 1 | 1);
    tr[ls].f1+=tr[rt].f1,tr[rs].f1+=tr[rt].f1*f[mid-l]+tr[rt].f2*f[mid-l+1];
    tr[ls].f2+=tr[rt].f2,tr[rs].f2+=tr[rt].f1*f[mid-l+1]+tr[rt].f2*f[mid-l+2];
    tr[rt].f1=tr[rt].f2=0;
//    cout << t[ls].f2 << " " << t[rs].f2 << endl;
    update(ls,mid-l+1),update(rs,r-mid);
}/*
long long ask(int k,int l,int r,int x,int y)
{
	if(x <= l && r <= y)	return tr[k].v %= mod;
	down(k,l,r);
	int mid = (l + r) >> 1;
	long long ans = 0;
	if(x <= mid)	ans = (ans + ask(k << 1,l,mid,x,y)) % mod;
	if(y > mid)		ans = (ans + ask(k << 1 | 1,mid + 1,r,x,y)) % mod;
	return ans;
}*/
int ask(int rt,int l,int r,int L,int R)
{
    if(L<=l&&r<=R)return tr[rt].v;
    down(rt,l,r);
    int res=0;
    int mid=(l+r)>>1;
    if(L<=mid)res+=ask(rt << 1,l,mid,L,R);
    if(mid<R)res+=ask(rt << 1 | 1,mid+1,r,L,R);
    return res%mod;
}
void change(int k,int l,int r,int x,int y,int em)
{
	if(x <= l && r <= y)
	{
		tr[k].f1 = (tr[k].f1 + f[em + l - x + 1]) % mod;
		tr[k].f2 = (tr[k].f2 + f[em + l - x + 2]) % mod;
		update(k,r - l + 1);
		return;
	}
	down(k,l,r);
	int mid = (l + r) >> 1;
	if(x <= mid)	change(k << 1,l,mid,x,y,em);
	if(y > mid)		change(k << 1 | 1,mid + 1,r,x,y,em);
	update(k,r - l + 1);
}/*
signed main()
{
//	freopen("d.in","r",stdin);
//	freopen("d.out","w",stdout);
	init();
	scanf("%lld%lld",&n,&m);
	for(int i = 1;i <= n;i ++)
	{
		scanf("%lld",&a[i]);
		a[i] %= mod;
	}
	for(int i = 1;i <= n;i ++)	sum[i] = ((sum[i - 1] + a[i]) % mod + mod) % mod;

	for(int i = 1,opt,l,r,x;i <= m;i ++)
	{
		scanf("%lld%lld%lld",&opt,&l,&r);
		if(opt == 2)	printf("%lld\n",((ask(1,1,n,l,r) + sum[r] - sum[l - 1]) % mod + mod) % mod);
		else
		{
//			scanf("%d",&x);
			change(1,1,n,l,r,0);
		}
//		for(int i = 1;i <= n * 4;i ++)	cout << tr[i].f1 << " " << tr[i].f2 << " " << tr[i].v << endl;
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}*/
signed main()
{
    scanf("%lld%lld",&n,&m);
    init();
    for(int i=1;i<=n;i++)scanf("%lld",&a[i]),sum[i]=sum[i-1]+a[i];//预处理前缀和

    while(m--)
    {
        int opt,l,r;
        scanf("%lld%lld%lld",&opt,&l,&r);
        if(opt==1)change(1,1,n,l,r,0);
        else printf("%lld\n",(ask(1,1,n,l,r)+sum[r]-sum[l-1]+mod)%mod);
//        for(int i = 1;i <= n * 4;i ++)	cout << t[i].f1 << " " << t[i].f2 << " " << t[i].v << endl;
    }

    return 0;
}
/*
5 3
1 2 3 4 5
1 1 5
2 1 5 2
1 1 5
*/
/*
5 3
1 2 3 4 5
1 1 5
2 1 1 2
1 1 5
*/


#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#define MogeKo qwq
using namespace std;
#define ls (now<<1)
#define rs (now<<1|1)
const int maxn = 2e6+10;
const int mod = 1e9+9;

long long n,m,x,y,op;
long long a[maxn],f[maxn];

struct tree {
	long long sum,c1,c2;
} t[maxn];

int read() {
	int x = 0,f = 1;
	char ch = getchar();
	while(ch < '0' || ch > '9') {
		if(ch == '-') f = -1;
		ch = getchar();
	}
	while('0' <= ch && ch <= '9') {
		x = (x<<3)+(x<<1) + ch-'0';
		ch = getchar();
	}
	return x * f;
}

long long getx(long long a1,long long a2,long long x) {
	if(x == 1) return a1 % mod;
	if(x == 2) return a2 % mod;
	return ( a1*f[x-2] + a2*f[x-1] ) % mod;
}

long long getsum(long long a1,long long a2,long long x) {
	if(x == 1) return a1 % mod;
	if(x == 2) return (a1+a2) % mod;
	return ( getx(a1,a2,x+2) - a2 + mod ) % mod;
}

void pushup(int now) {
	t[now].sum = (t[ls].sum + t[rs].sum) % mod;
}

void pushdown(int l,int r,int now) {
	if(!t[now].c1 && !t[now].c2) return;
	int mid = (l+r)>>1;
	long long a1,a2;
	a1 = t[now].c1;
	a2 = t[now].c2;
	t[ls].c1 = (t[ls].c1 + a1) % mod;
	t[ls].c2 = (t[ls].c2 + a2) % mod;
	t[ls].sum = (t[ls].sum + getsum(a1,a2,mid-l+1)) % mod;
	a1 = getx(t[now].c1,t[now].c2,mid-l+2);
	a2 = getx(t[now].c1,t[now].c2,mid-l+3);
	t[rs].c1 = (t[rs].c1 + a1) % mod;
	t[rs].c2 = (t[rs].c2 + a2) % mod;
	t[rs].sum = (t[rs].sum + getsum(a1,a2,r-mid)) % mod;
	t[now].c1 = t[now].c2 = 0;
}

void modify(int L,int R,int l,int r,int now) {
	if(L <= l && r <= R) {
		t[now].c1 = (t[now].c1 + f[l-L+1]) % mod;
		t[now].c2 = (t[now].c2 + f[l-L+2]) % mod;
		t[now].sum = (t[now].sum + getsum(f[l-L+1],f[l-L+2],r-l+1)) % mod;
		return;
	}
	pushdown(l,r,now);
	int mid = (l+r)>>1;
	if(L <= mid) modify(L,R,l,mid,ls);
	if(R > mid) modify(L,R,mid+1,r,rs);
	pushup(now);
}

long long query(int L,int R,int l,int r,int now) {
	long long ans = 0;
	if(L <= l && r <= R) {
		ans = t[now].sum;
		return (ans + mod) % mod;
	}
	pushdown(l,r,now);
	int mid = (l+r)>>1;
	if(L <= mid) ans = (ans + query(L,R,l,mid,ls)) % mod;
	if(R > mid) ans = (ans + query(L,R,mid+1,r,rs)) % mod;
	return (ans+mod)%mod;
}

void init() {
	f[1] = f[2] = 1;
	for(int i = 3; i <= n+2; i++)
		f[i] = (f[i-1] + f[i-2]) %mod;
}

int main() {
	n = read(),m = read();
	for(int i = 1; i <= n; i++) {
		x = read();
		a[i] = (a[i-1] + x) % mod;
	}
	init();
	while(m--) {
		op = read();
		x = read(), y = read();
		if(op == 1) modify(x,y,1,n,1);
		if(op == 2) printf("%lld\n",((a[y]-a[x-1]+query(x,y,1,n,1))%mod+mod)%mod);
	}
	return 0;
}


#include<cstdio>
#include<iostream>
#include<algorithm>
#define N 300005
#define int long long
#define mod 1000000009
using namespace std;

inline int read() {
    int f = 1, x = 0;char s = getchar();
    while (s < '0' || s > '9') {if (s == '-')f = -1;s = getchar();}
    while (s >= '0' && s <= '9') { x = x * 10 + s - '0';s = getchar();}
    return x * f;
}

int n, m;
struct T {
    int f1, f2, v;
} t[N * 20];
int a[N], f[N], sum[N];

void pushup(int k, int pos) {
    t[k].f1 %= mod, t[k].f2 %= mod;
    t[k].v = (t[k << 1].v + t[k << 1 | 1].v + (t[k].f1 * f[pos] + t[k].f2 * f[pos + 1] - t[k].f2) % mod) % mod;
}

void pushdn(int k, int l, int r) {
    if (t[k].f1 == 0 && t[k].f2 == 0) return;
    int mid = (l + r) >> 1;
    t[k << 1].f1 += t[k].f1, t[k << 1 | 1].f1 += t[k].f1 * f[mid - l] + t[k].f2 * f[mid - l + 1];
    t[k << 1].f2 += t[k].f2, t[k << 1 | 1].f2 += t[k].f1 * f[mid - l + 1] + t[k].f2 * f[mid - l + 2];
    t[k].f1 = t[k].f2 = 0;
    pushup(k << 1, mid - l + 1), pushup(k << 1 | 1, r - mid);
}

void update(int k, int l, int r, int L, int R) {
    if (L <= l && r <= R) {
        t[k].f1 += f[l - L + 1];
        t[k].f2 += f[l - L + 2];
        t[k].f1 %= mod, t[k].f2 %= mod;
        pushup(k, r - l + 1);
        return;
    }
    pushdn(k, l, r);
    int mid = (l + r) >> 1;
    if (L <= mid) update(k << 1, l, mid, L, R);
    if (mid < R) update(k << 1 | 1, mid + 1, r, L, R);
    pushup(k, r - l + 1);
}

int query(int k, int l, int r, int L, int R) {
    if (L <= l && r <= R) return t[k].v;
    pushdn(k, l, r); int res = 0,mid = (l + r) >> 1;
    if (L <= mid) res += query(k << 1, l, mid, L, R);
    if (mid < R) res += query(k << 1 | 1, mid + 1, r, L, R);
    return res % mod;
}

signed main() {
    n = read(), m = read();
    f[1] = 1, f[2] = 1;
    for (int i = 3; i <= n + 1; i++) f[i] = (f[i - 2] + f[i - 1]) % mod;
    for (int i = 1; i <= n; i++) a[i] = read(), sum[i] = sum[i - 1] + a[i];
    while (m--) {
        int opt = read(), l = read(), r = read();
        if (opt == 1) update(1, 1, n, l, r);
        else printf("%lld\n", (query(1, 1, n, l, r) + sum[r] - sum[l - 1] + mod) % mod);
    }
    return 0;
}


#include<bits/stdc++.h>
#define mod 1000000009
#define five 383008016
#define inv5 276601605
#define five1 691504013
#define five2 308495997
using namespace std;
int n,m;
long long a[300005];
int op,L,R;

int sqrtn;
int bl[300005];//block
int l[1005],r[1005],tt;
int siz[1005];//size
long long lazy1[1005],lazy2[1005];
long long sum[1005];

long long mi(long long n,long long p)
{
    if(n==0) return 0;
    if(p==0) return 1;
    long long yuan=1,mul=n;
    while(p)
    {
        if(p&1) yuan*=mul;
        yuan%=mod;
        mul*=mul;
        mul%=mod;
        p>>=1;
    }
    return yuan%mod;
}

long long f[300005];
long long fs[300005];
long long m1[300005],m2[300005];
inline void init()
{
    f[1]=f[2]=1;
    for(int i=3;i<=300000;i++) f[i]=(f[i-1]+f[i-2])%mod;
    for(int i=1;i<=300000;i++) fs[i]=(fs[i-1]+f[i])%mod;
    m1[0]=m2[0]=1;
    for(int i=1;i<=n;i++)
    {
        m1[i]=m1[i-1]*(five+1)%mod*mi(2,mod-2)%mod;
        m2[i]=m2[i-1]*(1-five+mod)%mod*mi(2,mod-2)%mod;
    }
}

inline void inblock()
{
    for(int i=1;i<=n/sqrtn;i++)
    {
        tt++;
        l[tt]=r[tt-1]+1;
        r[tt]=r[tt-1]+sqrtn;
        siz[tt]=r[tt]-l[tt]+1;
        for(int j=l[tt];j<=r[tt];j++) bl[j]=tt;
    }
    if(sqrtn*sqrtn!=n)
    {
        tt++;l[tt]=r[tt-1]+1;r[tt]=n;siz[tt]=r[tt]-l[tt]+1;
        for(int j=l[tt];j<=r[tt];j++) bl[j]=tt;
    }
}

inline void push_down()
{
    if(lazy1[bl[L]]!=0 || lazy2[bl[L]]!=0)
    {
        int tot=0;
        for(int i=l[bl[L]];i<=r[bl[L]];i++)
        {
            a[i]+=lazy1[bl[L]]*m1[tot]%mod*inv5%mod;
            a[i]-=lazy2[bl[L]]*m2[tot]%mod*inv5%mod;
            a[i]%=mod;
            tot++;
        }
        lazy1[bl[L]]=lazy2[bl[L]]=0;
    }
    if(lazy1[bl[R]]!=0 || lazy2[bl[R]]!=0)
    {
        int tot=0;
        for(int i=l[bl[R]];i<=r[bl[R]];i++)
        {
            a[i]+=lazy1[bl[R]]*m1[tot]%mod*inv5%mod;
            a[i]-=lazy2[bl[R]]*m2[tot]%mod*inv5%mod;
            a[i]%=mod;
            tot++;
        }
        lazy1[bl[R]]=lazy2[bl[R]]=0;
    }
//  cout<<"pushed:"<<endl;
//  for(int i=1;i<=n;i++) cout<<a[i]<<" "; cout<<endl;
}

inline void insert()
{
    push_down();
    if(bl[L]==bl[R])
    {
        int tot=1;
        for(int i=L;i<=R;i++)
        {
            a[i]+=f[tot]%mod; a[i]%=mod;
            tot++;
        }
        sum[bl[L]]+=fs[tot-1]%mod; sum[bl[L]]%=mod;
        return ;
    }

    int tot=1;
    for(int i=L;i<=r[bl[L]];i++)
    {
        a[i]+=f[tot]%mod; a[i]%=mod;
        sum[bl[L]]+=f[tot]%mod; sum[bl[L]]%=mod;
        tot++;
    }
    for(int i=bl[L]+1;i<bl[R];i++)
    {
        lazy1[i]+=m1[tot]%mod; lazy1[i]%=mod;
        lazy2[i]+=m2[tot]%mod; lazy2[i]%=mod;
        sum[i]+=fs[tot+siz[i]-1]-fs[tot-1]; sum[i]%=mod;
        tot+=siz[i];
    }
    for(int i=l[bl[R]];i<=R;i++)
    {
        a[i]+=f[tot]%mod; a[i]%=mod;
        sum[bl[R]]+=f[tot]%mod; sum[bl[R]]%=mod;
        tot++;
    }
}

inline void ask()
{
    long long anss=0;
    push_down();

    if(bl[L]==bl[R])
    {
        for(int i=L;i<=R;i++)
        {
            anss+=a[i]%mod;
            anss%=mod;
        }
        cout<<(anss%mod+mod)%mod<<endl;
        return ;
    }

    for(int i=L;i<=r[bl[L]];i++)
    {
        anss+=a[i]%mod;
        anss%=mod;
    }
    for(int i=l[bl[R]];i<=R;i++)
    {
        anss+=a[i]%mod;
        anss%=mod;
    }
    for(int i=bl[L]+1;i<bl[R];i++)
    {
        anss+=sum[i]%mod;
        anss%=mod;
    }
    cout<<(anss%mod+mod)%mod<<endl;
    return ;
}

int main()
{
//  freopen("rd.in","r",stdin);
//  freopen("my.out","w",stdout);
    ios::sync_with_stdio(0);
    cin>>n>>m;
    sqrtn=pow(n,0.6);
    inblock();
    init();
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        sum[bl[i]]+=a[i];
        sum[bl[i]]%=mod;
    }

//  for(int i=1;i<=n;i++) cout<<bl[i]<<" "; cout<<endl;
//  for(int i=1;i<=tt;i++) cout<<sum[i]<<" "; cout<<endl;
//  cout<<endl;
    while(m--)
    {
        cin>>op>>L>>R;
        if(op==1)
        {
            insert();
//          cout<<endl;
//          for(int i=1;i<=n;i++) cout<<a[i]<<" "; cout<<endl;
//          for(int i=1;i<=tt;i++) cout<<sum[i]<<" "; cout<<endl;
//          cout<<endl;
        }
        else
        {
            ask();
        }
    }
}


#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 9;
struct TREE {
	int one, two, sum;
} t[1200005];
int n, m, a[300005];
inline int pls(int x, int y) {
	x += y;
	return x >= mod ? x - mod : x;
}
struct Matrix {
	int a[3][3];
	Matrix() { memset(a, 0, sizeof(a)); }
	Matrix operator *(Matrix rhs) {
		Matrix c;
		for (int i = 0; i < 3; ++i)
			for (int j = 0; j < 3; ++j)
				if (a[i][j])
					for (int k = 0; k < 3; ++k)
						c.a[i][k] = pls(c.a[i][k], 1ll * a[i][j] * rhs.a[j][k] % mod);
		return c;
	}
} e, M[300005], u;
int calc(int &one, int &two, int len) {
	Matrix a = M[len];
	a.a[2][0] = 1ll * a.a[2][0] * one % mod;
	a.a[2][1] = 1ll * a.a[2][1] * two % mod;
	int ONE = (1ll * one * a.a[0][0] + 1ll * two * a.a[0][1]) % mod;
	int TWO = (1ll * one * a.a[1][0] + 1ll * two * a.a[1][1]) % mod;
	one = ONE, two = TWO;
	return pls(a.a[2][0], a.a[2][1]);
}
void down(int p, int l, int r, int mid) {
	if (t[p].one || t[p].two) {
		t[p << 1].one = pls(t[p << 1].one, t[p].one);
		t[p << 1].two = pls(t[p << 1].two, t[p].two);
		int one = t[p].one, two = t[p].two;
		t[p << 1].sum = pls(t[p << 1].sum, calc(one, two, mid - l + 1));
		t[p << 1 | 1].one = pls(t[p << 1 | 1].one, one);
		t[p << 1 | 1].two = pls(t[p << 1 | 1].two, two);
		t[p << 1 | 1].sum = pls(t[p << 1 | 1].sum, calc(one, two, r - mid));
		t[p].one = t[p].two = 0;
	}
}
void build(int p, int l, int r) {
	if (l == r) {
		t[p].sum = a[l];
		return;
	}
	int mid = l + r >> 1;
	build(p << 1, l, mid);
	build(p << 1 | 1, mid + 1, r);
	t[p].sum = pls(t[p << 1].sum, t[p << 1 | 1].sum);
}
void add(int p, int l, int r, int L, int R) {
	if (l > R || L > r) return;
	if (L <= l && r <= R) {
		int one = 1, two = 0;
		calc(one, two, l - L);
		t[p].one = pls(t[p].one, one);
		t[p].two = pls(t[p].two, two);
		t[p].sum = pls(t[p].sum, calc(one, two, r - l + 1));
		return;
	}
	int mid = l + r >> 1;
	down(p, l, r, mid);
	add(p << 1, l, mid, L, R);
	add(p << 1 | 1, mid + 1, r, L, R);
	t[p].sum = pls(t[p << 1].sum, t[p << 1 | 1].sum);
}
int qry(int p, int l, int r, int L, int R) {
	if (l > R || L > r) return 0;
	if (L <= l && r <= R) return t[p].sum;
	int mid = l + r >> 1;
	down(p, l, r, mid);
	return pls(qry(p << 1, l, mid, L, R), qry(p << 1 | 1, mid + 1, r, L, R));
}
int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i)
		scanf("%d", &a[i]);
	e.a[0][0] = e.a[1][1] = e.a[2][2] = 1;
	M[0] = e;
	u.a[0][1] = u.a[1][0] = u.a[1][1] = u.a[2][0] = u.a[2][1] = u.a[2][2] = 1;
	for (int i = 1; i <= n; ++i)
		M[i] = M[i - 1] * u;
	build(1, 1, n);
	for (int i = 1; i <= m; ++i) {
		int o, l, r;
		scanf("%d%d%d", &o, &l, &r);
		if (o == 1)
			add(1, 1, n, l, r);
		else
			printf("%d\n", qry(1, 1, n, l, r));
	}
	return 0;
}


#include<cstdio>
#include<iostream>
#define int long long
using namespace std;
const int mod = 1e9 + 9;
const int N = 300005;
int n,m;
long long f[N << 1],a[N],sum[N];
struct node{
	long long f1,f2,v;
	node(long long f1 = 0,long long f2 = 0,long long v = 0):f1(f1),f2(f2),v(v){};
}tr[N << 4];
void init()
{
	f[0] = 0;f[1] = 1;
	for(int i = 2;i <= 300001;i ++)	f[i] = (f[i - 1] + f[i - 2]) % mod;
}
void update(int k,int len)
{
	tr[k].f1 %= mod;	tr[k].f2 %= mod;
	tr[k].v = (((tr[k << 1].v + tr[k << 1 | 1].v) % mod + tr[k].f1 * f[len] % mod + tr[k].f2 * f[len + 1] % mod - tr[k].f2) % mod + mod) % mod;
}
void down(int k,int l,int r)
{
	if(tr[k].f1 == 0 && tr[k].f2 == 0)	return;
	int mid = (l + r) >> 1;
	tr[k << 1].f1 += tr[k].f1;
	tr[k << 1 | 1].f1 += (tr[k].f1 * f[mid - l] % mod + tr[k].f2 * f[mid - l + 1] % mod) % mod;
	tr[k << 1].f2 += tr[k].f2;
	tr[k << 1 | 1].f2 += (tr[k].f1 * f[mid - l + 1] % mod + tr[k].f2 * f[mid - l + 2] % mod) % mod;
	tr[k].f1 = tr[k].f2 = 0;
	update(k << 1,mid - l + 1);	update(k << 1 | 1,r - mid);
}
long long ask(int k,int l,int r,int x,int y)
{
	if(x <= l && r <= y)	return tr[k].v %= mod;
	down(k,l,r);
	int mid = (l + r) >> 1;
	long long ans = 0;
	if(x <= mid)	ans = (ans + ask(k << 1,l,mid,x,y)) % mod;
	if(y > mid)		ans = (ans + ask(k << 1 | 1,mid + 1,r,x,y)) % mod;
	return ans;
}
void change(int k,int l,int r,int x,int y,int em)
{
	if(x <= l && r <= y)
	{
		tr[k].f1 = (tr[k].f1 + f[em + l - x + 1]) % mod;
		tr[k].f2 = (tr[k].f2 + f[em + l - x + 2]) % mod;
		update(k,r - l + 1);
		return;
	}
	down(k,l,r);
	int mid = (l + r) >> 1;
	if(x <= mid)	change(k << 1,l,mid,x,y,em);
	if(y > mid)		change(k << 1 | 1,mid + 1,r,x,y,em);
	update(k,r - l + 1);
}
signed main()
{
//	freopen("d.in","r",stdin);
//	freopen("d.out","w",stdout);
	init();
	scanf("%lld%lld",&n,&m);
	for(int i = 1;i <= n;i ++)	scanf("%lld",&a[i]);
	for(int i = 1;i <= n;i ++)	sum[i] = (sum[i - 1] + a[i]) % mod;
	for(int i = 1,opt,l,r,x;i <= m;i ++)
	{
		scanf("%lld%lld%lld",&opt,&l,&r);
		if(opt == 1)	printf("%lld\n",((ask(1,1,n,l,r) + sum[r] - sum[l - 1]) % mod + mod) % mod);
		else
		{
			scanf("%d",&x);
			change(1,1,n,l,r,x - 1);
		}
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}
/*
5 3
1 2 3 4 5
1 1 5
2 1 5 2
1 1 5
*/
/*
5 3
1 2 3 4 5
1 1 5
2 1 1 2
1 1 5
*/


#include<map>
#include<queue>
#include<cmath>
#include<bitset>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
inline int read(){
	int ans=0,fh=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-') fh=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
		ans=(ans<<1)+(ans<<3)+ch-'0',ch=getchar();
	return ans*fh;
}
const int maxn=3e1+100;
const ll a1=276601605,P=1e9+9;
const ll q[2]={691504013,308495997},iq[2]={308495996,691504012};
int n,m,a[maxn];
ll p[maxn<<2][2],sum[maxn<<2],pw[2][maxn];
inline void updata(int o){sum[o]=(sum[o<<1]+sum[o<<1|1])%P;}
void build(int o,int l,int r){
	if(l==r){sum[o]=p[o][0]=a[l];return;}
	int mid=l+r>>1;
	build(o<<1,l,mid),build(o<<1|1,mid+1,r);
	updata(o);
}
inline void ycl(){
	pw[0][0]=pw[1][0]=1;
	for(int i=1;i<=n;i++) pw[0][i]=pw[0][i-1]*q[0]%P;
	for(int i=1;i<=n;i++) pw[1][i]=pw[1][i-1]*q[1]%P;
}
inline void calc(int o,int len){
	updata(o);
	(sum[o]+=p[o][0]*(1-pw[0][len])%P*iq[0]%P)%=P;
	(sum[o]+=p[o][1]*(1-pw[1][len])%P*iq[1]%P)%=P;
}
inline void pushdown(int o,int l,int r){
	if(!p[o][0]&&!p[o][1]) return;
	int mid=l+r>>1,lc=o<<1,rc=o<<1|1,len=mid-l+1;
	ll p1=p[o][0],p2=p[o][1];
	p[o][0]=p[o][1]=0;
	(p[lc][0]+=p1)%=P,(p[lc][1]+=p2)%=P;
	(p[rc][0]+=p1*pw[0][len]%P)%=P,(p[rc][1]+=p2*pw[1][len]%P)%=P;
	calc(lc,mid-l+1),calc(rc,r-mid);
}
void revise(int o,int l,int r,int ql,int qr,ll p1,ll p2){
	if(ql==l&&qr==r){
		(p[o][0]+=p1)%=P,(p[o][1]+=p2)%=P;
		calc(o,r-l+1);return;
	}
	int mid=l+r>>1;pushdown(o,l,r);
	if(ql<=mid) revise(o<<1,l,mid,ql,min(qr,mid),p1,p2);
	int len=ql<=mid?mid-ql+1:0;
	if(qr>mid) revise(o<<1|1,mid+1,r,max(ql,mid+1),qr,p1*pw[0][len]%P,p2*pw[1][len]%P);
	updata(o);
}
ll query(int o,int l,int r,int ql,int qr){
	if(ql==l&&qr==r) return sum[o];
	pushdown(o,l,r);int mid=l+r>>1;
	ll Ans=0;
	if(ql<=mid) Ans=(Ans+query(o<<1,l,mid,ql,min(qr,mid)))%P;
	if(qr>mid) Ans=(Ans+query(o<<1|1,mid+1,r,max(ql,mid+1),qr))%P;
	return Ans;
}
int main(){
//	freopen("nh.in","r",stdin);
	//freopen("zhy.out","w",stdout);
	n=read(),m=read(),ycl();
	for(int i=1;i<=n;i++) a[i]=read();
	build(1,1,n);
	while(m--){
		int ms=read(),l=read(),r=read();
		if(ms==1) revise(1,1,n,l,r,a1*q[0]%P,-a1*q[1]%P);
		else printf("%I64d\n",(query(1,1,n,l,r)+P)%P);
	}
	return 0;
}


#include<bits/stdc++.h>
#define int long long
using namespace std;
int read(){
	int c=0,nx,sign=1;
	do{
		nx=getchar()-'0';
		if(nx=='-'-'0')
			sign=-1;
	}while(nx<0 or nx>9);
	while(nx>=0 and nx<=9){
		c=c*10+nx;
		nx=getchar()-'0';
	}
	return sign*c;
}
const int N=3e5+10,mod=1e9+7;
int fib[2*N],a[N];
struct stree{
	int tot,a,b;
	stree *ls,*rs;
}c[4*N];
stree* New(){
	static int now=0;
	stree &s=c[++now];
	s.tot=s.a=s.b=0;
	s.ls=s.rs=c;
	return c+now;
}
inline int h(int a,int b,int x){
	if(x>=3)
		return (a*fib[x-2] + b*fib[x-1]) % mod;
	else if(x==2)
		return b;
	else
		return a;
}
inline void pd(stree &s,int a,int b,int l,int r){
	s.a = (s.a + a) % mod;
	s.b = (s.b + b) % mod;
	s.tot = (s.tot + h(a,b,r-l+3) - b + mod) % mod;
}
void pushdown(stree &s,int l,int r){
	if(!s.a and !s.b or l==r)
		return ;
	int mid=(l+r)>>1;
	int &a=s.a,&b=s.b;
	pd(*s.ls,a,b,l,mid);
	pd(*s.rs,h(a,b,mid+2-l),h(a,b,mid+3-l),mid+1,r);
	a=b=0;
}
inline void pushup(stree &s){
	s.tot = (s.ls->tot + s.rs->tot) % mod;
}
void add(int ql,int qr,stree &s,int l,int r){
	if(ql<=l and r<=qr){
		pd(s,fib[l-ql+1],fib[l-ql+2],l,r);
		return ;
	}
	pushdown(s,l,r);
	int mid=(l+r)>>1;
	if(ql<=mid)
		add(ql,qr,*s.ls,l,mid);
	if(qr>mid)
		add(ql,qr,*s.rs,mid+1,r);
	pushup(s);
}
int query(int ql,int qr,stree &s,int l,int r){
	if(ql<=l and r<=qr){
		return s.tot;
	}
	pushdown(s,l,r);
	int mid=(l+r)>>1,ans=0;
	if(ql<=mid)
		ans+=query(ql,qr,*s.ls,l,mid);
	if(qr>mid)
		ans+=query(ql,qr,*s.rs,mid+1,r);
	return ans % mod;
}
void build(stree &s,int l,int r){
	if(l==r){
		s.tot=a[l];
		return ;
	}
	s.ls = New();
	s.rs = New();
	int mid = (l + r) >> 1;
	build(*s.ls,l,mid);
	build(*s.rs,mid+1,r);
	pushup(s);
}

signed main(){
	fib[1]=1;
	for(int i=2;i<=4e5;i++)
		fib[i]=(fib[i-1] + fib[i-2]) % mod;
	int n=read(),t=read();
	for(int i=1;i<=n;i++)
		a[i]=read();
	stree &root=*New();
	build(root,1,n);

	while(t--){
		int ord=read(),l=read(),r=read();
		switch(ord){
			case 1:
				add(l,r,root,1,n);
				break;
			case 2:
				printf("%lld\n",query(l,r,root,1,n));
				break;
		}
//		cout<<'*';
//		for(int i=1;i<=n;i++)
//			cout<<query(i,i,root,1,n)<<' ';
//		cout<<endl;
	}
}


// Author: wlzhouzhuan
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define ull unsigned long long
#define rint register int
#define rep(i, l, r) for (rint i = l; i <= r; i++)
#define per(i, l, r) for (rint i = l; i >= r; i--)
#define mset(s, _) memset(s, _, sizeof(s))
#define pb push_back
#define pii pair <int, int>

char buf[1 << 21], *p1 = buf, *p2 = buf;
int getc() {
  return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
}
//#define getc getchar
int read() {
  int num = 0, neg = 1;
  char ch = getc();
  while (!isdigit(ch)) { if (ch == '-') neg = -1; ch = getc(); }
  while (isdigit(ch)) { num = 10 * num + ch - '0'; ch = getc(); }
  return neg * num;
}
void print(int x) {
  if (x < 0) { putchar('-'); x = -x; }
  if (x >= 10) print(x / 10);
  putchar(x % 10 + '0');
}

const int mod = 1e9 + 9;
const int N = 300005;

/*
f[x - l + 1] = f[x + 1] * f[-l + 1] + f[x] * f[-l]
lzy1: sum{f[-l+1]}, lzy2: sum{f[-l]}
*/
int fib[N], rfib[N], sumf[N];
void init(int n) {
  fib[1] = 1, fib[2] = 1, rfib[1] = 1, rfib[2] = mod - 1;
  sumf[1] = 1, sumf[2] = 2;
  for (rint i = 3; i <= n; i++) {
    fib[i] = (fib[i - 1] + fib[i - 2]) % mod;
    sumf[i] = (sumf[i - 1] + fib[i]) % mod;
    rfib[i] = (i & 1) ? fib[i] : mod - fib[i];
  }
}
int a[N], suma[N], n, m;
struct SegmentTree {
  #define ls (u << 1)
  #define rs (u << 1 | 1)
  int lzy1[N << 2], lzy2[N << 2], sum[N << 2];
  void pushup(int u) {
    sum[u] = (sum[ls] + sum[rs]) % mod;
  }
  void pushdown(int u, int l, int r) {
    if (lzy1[u] || lzy2[u]) {
      int mid = l + r >> 1;
      lzy1[ls] = (lzy1[ls] + lzy1[u]) % mod, lzy2[ls] = (lzy2[ls] + lzy2[u]) % mod;
      lzy1[rs] = (lzy1[rs] + lzy1[u]) % mod, lzy2[rs] = (lzy2[rs] + lzy2[u]) % mod;
      sum[ls] = (sum[ls] + 1ll * (sumf[mid + 1] - sumf[l] + mod) % mod * lzy1[u] % mod) % mod;
      sum[ls] = (sum[ls] + 1ll * (sumf[mid] - sumf[l - 1] + mod) % mod * lzy2[u] % mod) % mod;
      sum[rs] = (sum[rs] + 1ll * (sumf[r + 1] - sumf[mid + 1] + mod) % mod * lzy1[u] % mod) % mod;
      sum[rs] = (sum[rs] + 1ll * (sumf[r] - sumf[mid] + mod) % mod * lzy2[u] % mod) % mod;
      lzy1[u] = lzy2[u] = 0;
    }
  }
  void update(int u, int l, int r, int ql, int qr, int v1, int v2) {
    if (ql <= l && r <= qr) {
      lzy1[u] = (lzy1[u] + v1) % mod;
      lzy2[u] = (lzy2[u] + v2) % mod;
      sum[u] = (sum[u] + 1ll * (sumf[r + 1] - sumf[l] + mod) % mod * v1 % mod) % mod;
      sum[u] = (sum[u] + 1ll * (sumf[r] - sumf[l - 1] + mod) % mod * v2 % mod) % mod;
      return ;
    }
    pushdown(u, l, r);
    int mid = l + r >> 1;
    if (ql <= mid) update(ls, l, mid, ql, qr, v1, v2);
    if (qr > mid) update(rs, mid + 1, r, ql, qr, v1, v2);
    pushup(u);
  }
  int query(int u, int l, int r, int ql, int qr) {
    if (ql <= l && r <= qr) {
      return sum[u];
    }
    pushdown(u, l, r);
    int mid = l + r >> 1, ret = 0;
    if (ql <= mid) ret = (ret + query(ls, l, mid, ql, qr)) % mod;
    if (qr > mid) ret = (ret + query(rs, mid + 1, r, ql, qr)) % mod;
    return ret;
  }
} smt;

int main() {
  n = read(), m = read();
  for (rint i = 1; i <= n; i++) {
    a[i] = read();
    suma[i] = (suma[i - 1] + a[i]) % mod;
  }
  init(n + 3);
  while (m--) {
    int opt = read(), l = read(), r = read();
    if (opt == 1) smt.update(1, 1, n, l, r, rfib[l - 1], rfib[l]);
    else printf("%d\n", (suma[r] - suma[l - 1] + mod + smt.query(1, 1, n, l, r)) % mod);
  }
  return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
long long int seg[4*maxn];
long long int lazy[4*maxn];
long long int lazy2[4*maxn];
long long int bak[4*maxn];
long long int fibo[4*maxn];
long long int fiboo[4*maxn];
int mod=1e9+7;
void build(int v,int l,int r){
	if(r-l==1){
		seg[v]=bak[l];
		seg[v]%=mod;
		return ;
	}
	int mid = l+r;
	mid /= 2;
	build(2*v,l,mid);
	build(2*v+1,mid,r);
	seg[v]=seg[2*v]+seg[2*v+1];
	seg[v]%=mod;
}
void shift(int v,int l,int r){
	if(lazy2[v]==0){
		return ;
	}
	int mid=l+r>>1;
	lazy[2*v]+=lazy[v];
	lazy[2*v]%=mod;
	lazy2[2*v]+=lazy2[v];
	lazy[2*v+1]%=mod;
	seg[2*v]+=(((1ll*lazy2[v]*(fiboo[mid-l-2]+1))%mod)+(1ll*lazy[v]*fiboo[mid-l-1])%mod)%mod;
	seg[2*v]%=mod;
	lazy[2*v+1]+=(((1ll*lazy2[v]*(fibo[mid-l]))%mod)+((1ll*lazy[v]*fibo[mid-l+1])%mod))%mod;
	lazy[2*v+1]%=mod;
	lazy2[2*v+1]+=(((1ll*lazy2[v]*(fibo[(mid-l)-1]))%mod)+((1ll*lazy[v]*fibo[mid-l])%mod))%mod;
	lazy2[2*v+1]%mod;
	long long int at=(((1ll*lazy2[v]*(fibo[mid-l]))%mod)+((1ll*lazy[v]*fibo[mid-l+1])%mod))%mod;
	long long int bak2=(((1ll*lazy2[v]*(fibo[(mid-l)-1]))%mod)+(((1ll*lazy[v]*fibo[mid-l])%mod)))%mod;
	seg[2*v+1]+=(((1ll*at*fiboo[r-mid-1])%mod)+((1ll*bak2*(fiboo[r-mid-2]+1))%mod))%mod;
	seg[2*v+1]%=mod;
	lazy[v]=0;
	lazy2[v]=0;
}
void update(int v,int l,int r,int x,int y){
           if(y<=l||x>=r){
           	//shift(v,l,r);
                      return;
           }
           else if(x<=l&&r<=y){
                      lazy[v]+=fibo[l-x+2];
                      lazy[v]%=mod;
                      lazy2[v]+=fibo[l-x+1];
                      lazy2[v]%=mod;
                      //cout<<lazy[v]<<" "<<lazy2[v]<<" "<<l<<" "<<r<<endl;
                      seg[v]+=(((1ll*fibo[l-x+2]*(fiboo[r-l-1]))%mod)+((1ll*fibo[l-x+1]*(fiboo[r-l-2]+1))%mod))%mod;
                      seg[v]%=mod;
                      //shift(v,l,r);
             //         cout<<seg[v]<<" "<<v<<endl;
             return ;
           }
                      shift(v,l,r);
           int mid=l+r>>1;
           update(2*v,l,mid,x,y);
           update((2*v)+1,mid,r,x,y);
           seg[v]=seg[2*v]+seg[(2*v)+1];
           //cout<<seg[v]<<" "<<v<<endl;
           seg[v]%=mod;
}
int get(int v,int l,int r,int x,int y){
           if(y<=l||x>=r){
                      return 0;
           }
           else if(x<=l&&r<=y){
                      return seg[v];
           }
           shift(v,l,r);
           int mid=l+r>>1;
           long long int X = get(2*v,l,mid,x,y) + get(2*v+1,mid,r,x,y);
           seg[v]=seg[v*2]+seg[2*v+1];
           seg[v]%=mod;
           x%=mod;
           return X;
}
int main(){
	fibo[1]=1;
	fibo[2]=1;
	for(int i=3;i<=100000;i++){
		fibo[i]=fibo[i-1]+fibo[i-2];
		fibo[i]%=mod;
	}
     for(int i=1;i<=100000;i++){
     	fiboo[i]=fiboo[i-1]+fibo[i];
     	fiboo[i]%=mod;
	 }

	int n;
	int m;
	cin>>n>>m;
	for(int i=0;i<n;i++){
		cin>>bak[i];
	}
	build(1,0,n);
	while(m>0){
		m--;
		int g;
		cin>>g;
		if(g==2){
			int l;
			int r;
			cin>>l>>r;
			long long int f=get(1,0,n,l-1,r);
			f%=mod;
			cout<<f<<endl;
		}
		else{
			int l;
			int r;
			cin>>l>>r;
			update(1,0,n,l-1,r);
		}
	//	cout<<seg[3]<<endl;
	}
return 0;
}


//be nam KHODA
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
long long int seg[4*maxn];
long long int lazy[4*maxn];
long long int lazy2[4*maxn];
long long int bak[4*maxn];
long long int fibo[4*maxn];
long long int fiboo[4*maxn];
const long long int mod=1e9+9;
void build(int v,int l,int r){
	if(r-l==1){
		seg[v]=bak[l];
		seg[v]%=mod;
		return ;
	}
	long long int mid = l+r>>1;
	build(2*v,l,mid);
	build(2*v+1,mid,r);
	seg[v]=seg[2*v]+seg[2*v+1];
	seg[v]%=mod;
}
void shift(int v,int l,int r){
	if(lazy2[v]==0){
		return ;
	}
	long long int mid=l+r>>1;
	lazy[2*v]+=lazy[v];
	lazy[2*v]%=mod;
	lazy2[2*v]+=lazy2[v];
	lazy[2*v+1]%=mod;
	long long int at=lazy[v]%mod;
	long long int bak2=lazy2[v]%mod;
	seg[2*v]+=(((1ll*bak2*(fiboo[mid-l-2]+1))%mod)+(1ll*at*fiboo[mid-l-1])%mod);
	seg[2*v]%=mod;
	lazy[2*v+1]+=(((1ll*bak2*(fibo[mid-l]))%mod)+((1ll*at*fibo[mid-l+1])%mod));
	lazy[2*v+1]%=mod;
	lazy2[2*v+1]+=(((1ll*bak2*(fibo[(mid-l)-1]))%mod)+((1ll*at*fibo[mid-l])%mod));
	lazy2[2*v+1]%=mod;
	long long int d=at;
	d%=mod;
	at=(((1ll*bak2*(fibo[mid-l]))%mod)+((1ll*at*fibo[mid-l+1])%mod));
	at%=mod;
	bak2=(((1ll*bak2*(fibo[(mid-l)-1]))%mod)+(((1ll*d*fibo[mid-l])%mod)));
	bak2%=mod;
	seg[2*v+1]+=(((1ll*at*fiboo[r-mid-1])%mod)+((1ll*bak2*(fiboo[r-mid-2]+1))%mod));
	seg[2*v+1]%=mod;
	lazy[v]=0;
	lazy2[v]=0;
}
void update(int v,int l,int r,int x,int y){
           if(y<=l||x>=r){
           	//shift(v,l,r);
                      return;
           }
           else if(x<=l&&r<=y){
                      lazy[v]+=fibo[l-x+2];
                      lazy[v]%=mod;
                      lazy2[v]+=fibo[l-x+1];
                      lazy2[v]%=mod;
                      //cout<<lazy[v]<<" "<<lazy2[v]<<" "<<l<<" "<<r<<endl;
                      seg[v]+=(((1ll*fibo[l-x+2]*(fiboo[r-l-1]))%mod)+((1ll*fibo[l-x+1]*(fiboo[r-l-2]+1))%mod));
                      seg[v]%=mod;
                      //shift(v,l,r);
             //         cout<<seg[v]<<" "<<v<<endl;
             return ;
           }
                      shift(v,l,r);
           long long int mid=l+r>>1;
           update(2*v,l,mid,x,y);
           update((2*v)+1,mid,r,x,y);
           seg[v]=seg[2*v]+seg[(2*v)+1];
           //cout<<seg[v]<<" "<<v<<endl;
           seg[v]%=mod;
}
long long int get(int v,int l,int r,int x,int y){
           if(y<=l||x>=r){
                      return 0;
           }
           else if(x<=l&&r<=y){
                      return seg[v];
           }
           shift(v,l,r);
           long long int mid=l+r>>1;
           long long int X=get(2*v,l,mid,x,y)+get(2*v+1,mid,r,x,y);
           seg[v]=seg[v*2]+seg[2*v+1];
           seg[v]%=mod;
           X%=mod;
           return X;
}
int main(){
	int n;
	int m;
	cin>>n>>m;
	for(int i=0;i<n;i++){
		cin>>bak[i];
	}
	fibo[1]=1;
	fibo[2]=1;
	for(int i=3;i<=n;i++){
		fibo[i]=fibo[i-1]+fibo[i-2];
		fibo[i]%=mod;
	}
     for(int i=1;i<=n;i++){
     	fiboo[i]=fiboo[i-1]+fibo[i];
     	fiboo[i]%=mod;
	 }
	build(1,0,n);
	while(m>0){
		m--;
		int g;
		cin>>g;
		if(g==2){
			int l;
			int r;
			cin>>l>>r;
			long long int f=get(1,0,n,l-1,r);
			f%=mod;
			cout<<f<<endl;
		}
		else{
			int l;
			int r;
			cin>>l>>r;
			update(1,0,n,l-1,r);
		}
	//	cout<<seg[3]<<endl;
	}
return 0;
}


//be nam KHODA
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
long long int seg[4*maxn];
long long int lazy[4*maxn];
long long int lazy2[4*maxn];
long long int bak[4*maxn];
long long int fibo[4*maxn];
long long int fiboo[4*maxn];
long long int mod=1e9+9;
void build(int v,int l,int r){
	if(r-l==1){
		seg[v]=bak[l];
		seg[v]%=mod;
		return ;
	}
	int mid = l+r;
	mid /= 2;
	build(2*v,l,mid);
	build(2*v+1,mid,r);
	seg[v]=seg[2*v]+seg[2*v+1];
	seg[v]%=mod;
}
void shift(int v,int l,int r){
	if(lazy2[v]==0){
		return ;
	}
	int mid=l+r>>1;
	lazy[2*v]+=lazy[v];
	lazy[2*v]%=mod;
	lazy2[2*v]+=lazy2[v];
	lazy[2*v+1]%=mod;
	seg[2*v]+=(((1ll*lazy2[v]*(fiboo[mid-l-2]+1))%mod)+(1ll*lazy[v]*fiboo[mid-l-1])%mod)%mod;
	seg[2*v]%=mod;
	lazy[2*v+1]+=(((1ll*lazy2[v]*(fibo[mid-l]))%mod)+((1ll*lazy[v]*fibo[mid-l+1])%mod))%mod;
	lazy[2*v+1]%=mod;
	lazy2[2*v+1]+=(((1ll*lazy2[v]*(fibo[(mid-l)-1]))%mod)+((1ll*lazy[v]*fibo[mid-l])%mod))%mod;
	lazy2[2*v+1]%=mod;
	long long int at=(((1ll*lazy2[v]*(fibo[mid-l]))%mod)+((1ll*lazy[v]*fibo[mid-l+1])%mod))%mod;
	long long int bak2=(((1ll*lazy2[v]*(fibo[(mid-l)-1]))%mod)+(((1ll*lazy[v]*fibo[mid-l])%mod)))%mod;
	seg[2*v+1]+=(((1ll*at*fiboo[r-mid-1])%mod)+((1ll*bak2*(fiboo[r-mid-2]+1))%mod))%mod;
	seg[2*v+1]%=mod;
	lazy[v]=0;
	lazy2[v]=0;
}
void update(int v,int l,int r,int x,int y){
           if(y<=l||x>=r){
           	//shift(v,l,r);
                      return;
           }
           else if(x<=l&&r<=y){
                      lazy[v]+=fibo[l-x+2];
                      lazy[v]%=mod;
                      lazy2[v]+=fibo[l-x+1];
                      lazy2[v]%=mod;
                      //cout<<lazy[v]<<" "<<lazy2[v]<<" "<<l<<" "<<r<<endl;
                      seg[v]+=(((1ll*fibo[l-x+2]*(fiboo[r-l-1]))%mod)+((1ll*fibo[l-x+1]*(fiboo[r-l-2]+1))%mod))%mod;
                      seg[v]%=mod;
                      //shift(v,l,r);
             //         cout<<seg[v]<<" "<<v<<endl;
             return ;
           }
                      shift(v,l,r);
           int mid=l+r>>1;
           update(2*v,l,mid,x,y);
           update((2*v)+1,mid,r,x,y);
           seg[v]=seg[2*v]+seg[(2*v)+1];
           //cout<<seg[v]<<" "<<v<<endl;
           seg[v]%=mod;
}
long long int get(int v,int l,int r,int x,int y){
           if(y<=l||x>=r){
                      return 0;
           }
           else if(x<=l&&r<=y){
                      return seg[v];
           }
           shift(v,l,r);
           int mid=l+r>>1;
           long long int X=get(2*v,l,mid,x,y)+get(2*v+1,mid,r,x,y);
           seg[v]=seg[v*2]+seg[2*v+1];
           seg[v]%=mod;
           X%=mod;
           return X;
}
int main(){
	fibo[1]=1;
	fibo[2]=1;
	for(int i=3;i<=100000;i++){
		fibo[i]=fibo[i-1]+fibo[i-2];
		fibo[i]%=mod;
	}
     for(int i=1;i<=100000;i++){
     	fiboo[i]=fiboo[i-1]+fibo[i];
     	fiboo[i]%=mod;
	 }

	int n;
	int m;
	cin>>n>>m;
	for(int i=0;i<n;i++){
		cin>>bak[i];
	}
	build(1,0,n);
	while(m>0){
		m--;
		int g;
		cin>>g;
		if(g==2){
			int l;
			int r;
			cin>>l>>r;
			long long int f=get(1,0,n,l-1,r);
			f%=mod;
			cout<<f<<endl;
		}
		else{
			int l;
			int r;
			cin>>l>>r;
			update(1,0,n,l-1,r);
		}
	//	cout<<seg[3]<<endl;
	}
return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
long long int seg[4*maxn];
long long int lazy[4*maxn];
long long int lazy2[4*maxn];
long long int bak[4*maxn];
long long int fibo[4*maxn];
long long int fiboo[4*maxn];
int mod=1e9+7;
long long int ok(long long int &k){
	if(k>=mod){
		k-=mod;
	}
	return k;
}
void build(int v,int l,int r){
	if(r-l==1){
		seg[v]=bak[l];
		ok(seg[v]);
		return ;
	}
	int mid = l+r;
	mid /= 2;
	build(2*v,l,mid);
	build(2*v+1,mid,r);
	seg[v]=seg[2*v]+seg[2*v+1];
	ok(seg[v]);
}
void shift(int v,int l,int r){
	if(lazy2[v]==0||lazy[v]==0){
		return ;
	}
	int mid=l+r;
	mid/=2;
	lazy[2*v]+=lazy[v];
	ok(lazy[2*v]);
	lazy2[2*v]+=lazy2[v];
	ok(lazy2[2*v]);
	seg[2*v]+=(1ll*lazy2[v]*(fiboo[mid-l-2]+1))+(1ll*lazy[v]*fiboo[mid-l-1]);
	ok(seg[2*v]);
	lazy[2*v+1]+=(1ll*lazy2[v]*(fibo[mid-l]))+(1ll*lazy[v]*fibo[mid-l+1]);
	ok(lazy[2*v+1]);
	lazy2[2*v+1]+=(1ll*lazy2[v]*(fibo[(mid-l)-1]))+(1ll*lazy[v]*fibo[mid-l]);
	ok(lazy2[2*v+1]);
	long long int at=(1ll*lazy2[v]*(fibo[mid-l]))+(1ll*lazy[v]*fibo[mid-l+1]);
	ok(at);
	long long int bak2=(1ll*lazy2[v]*(fibo[(mid-l)-1]))+(1ll*lazy[v]*fibo[mid-l]);
	ok(bak2);
	seg[2*v+1]+=(1ll*at*fiboo[r-mid-1])+(1ll*bak2*(fiboo[r-mid-2]+1));
	ok(seg[2*v+1]);
	lazy[v]=0;
	lazy2[v]=0;
}
void update(int v,int l,int r,int x,int y){
           if(y<=l||x>=r){
           	//shift(v,l,r);
                      return;
           }
           else if(x<=l&&r<=y){
                      lazy[v]+=fibo[l-x+2];
                      ok(lazy[v]);
                      lazy2[v]+=fibo[l-x+1];
                      //cout<<lazy[v]<<" "<<lazy2[v]<<" "<<l<<" "<<r<<endl;
                      ok(lazy2[v]);
                      seg[v]+=(fibo[l-x+2]*(fiboo[r-l-1]))+(fibo[l-x+1]*(fiboo[r-l-2]+1));
                     ok(seg[v]);
                      //shift(v,l,r);
             //         cout<<seg[v]<<" "<<v<<endl;
             return ;
           }
                      shift(v,l,r);
           int mid=l+r;
           mid/=2;
           update(2*v,l,mid,x,y);
           update((2*v)+1,mid,r,x,y);
           seg[v]=seg[2*v]+seg[(2*v)+1];
           //cout<<seg[v]<<" "<<v<<endl;
           ok(seg[v]);
}
int get(int v,int l,int r,int x,int y){
           if(y<=l||x>=r){
                      return 0;
           }
           else if(x<=l&&r<=y){
                      return seg[v];
           }
           shift(v,l,r);
           int mid=l+r;
           mid/=2;
           long long int X = get(2*v,l,mid,x,y) + get(2*v+1,mid,r,x,y);
           seg[v]=seg[v*2]+seg[2*v+1];
           ok(X);
           return X;
}
int main(){
	fibo[1]=1;
	fibo[2]=1;
	for(int i=3;i<=100000;i++){
		fibo[i]=fibo[i-1]+fibo[i-2];
		fibo[i]=ok(fibo[i]);
	}
     for(int i=1;i<=100000;i++){
     	fiboo[i]=fiboo[i-1]+fibo[i];
     	ok(fiboo[i]);
	 }

	int n;
	int m;
	cin>>n>>m;
	for(int i=0;i<n;i++){
		cin>>bak[i];
	}
	build(1,0,n);
	while(m>0){
		m--;
		int g;
		cin>>g;
		if(g==2){
			int l;
			int r;
			cin>>l>>r;
			cout<<get(1,0,n,l-1,r)<<endl;
		}
		else{
			int l;
			int r;
			cin>>l>>r;
			update(1,0,n,l-1,r);
		}
	//	cout<<seg[3]<<endl;
	}
return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
long long int seg[4*maxn];
long long int lazy[4*maxn];
long long int lazy2[4*maxn];
long long int bak[4*maxn];
long long int fibo[4*maxn];
long long int fiboo[4*maxn];
long long int mod=1e9+9;
void build(int v,int l,int r){
	if(r-l==1){
		seg[v]=bak[l];
		seg[v]%=mod;
		return ;
	}
	int mid = l+r;
	mid /= 2;
	build(2*v,l,mid);
	build(2*v+1,mid,r);
	seg[v]=seg[2*v]+seg[2*v+1];
	seg[v]%=mod;
}
void shift(int v,int l,int r){
	if(lazy2[v]==0){
		return ;
	}
	int mid=l+r>>1;
	lazy[2*v]+=lazy[v];
	lazy[2*v]%=mod;
	lazy2[2*v]+=lazy2[v];
	lazy[2*v+1]%=mod;
	seg[2*v]+=(((1ll*lazy2[v]*(fiboo[mid-l-2]+1))%mod)+(1ll*lazy[v]*fiboo[mid-l-1])%mod)%mod;
	seg[2*v]%=mod;
	lazy[2*v+1]+=(((1ll*lazy2[v]*(fibo[mid-l]))%mod)+((1ll*lazy[v]*fibo[mid-l+1])%mod))%mod;
	lazy[2*v+1]%=mod;
	lazy2[2*v+1]+=(((1ll*lazy2[v]*(fibo[(mid-l)-1]))%mod)+((1ll*lazy[v]*fibo[mid-l])%mod))%mod;
	lazy2[2*v+1]%=mod;
	long long int at=(((1ll*lazy2[v]*(fibo[mid-l]))%mod)+((1ll*lazy[v]*fibo[mid-l+1])%mod))%mod;
	long long int bak2=(((1ll*lazy2[v]*(fibo[(mid-l)-1]))%mod)+(((1ll*lazy[v]*fibo[mid-l])%mod)))%mod;
	seg[2*v+1]+=(((1ll*at*fiboo[r-mid-1])%mod)+((1ll*bak2*(fiboo[r-mid-2]+1))%mod))%mod;
	seg[2*v+1]%=mod;
	lazy[v]=0;
	lazy2[v]=0;
}
void update(int v,int l,int r,int x,int y){
           if(y<=l||x>=r){
           	//shift(v,l,r);
                      return;
           }
           else if(x<=l&&r<=y){
                      lazy[v]+=fibo[l-x+2];
                      lazy[v]%=mod;
                      lazy2[v]+=fibo[l-x+1];
                      lazy2[v]%=mod;
                      //cout<<lazy[v]<<" "<<lazy2[v]<<" "<<l<<" "<<r<<endl;
                      seg[v]+=(((1ll*fibo[l-x+2]*(fiboo[r-l-1]))%mod)+((1ll*fibo[l-x+1]*(fiboo[r-l-2]+1))%mod))%mod;
                      seg[v]%=mod;
                      //shift(v,l,r);
             //         cout<<seg[v]<<" "<<v<<endl;
             return ;
           }
                      shift(v,l,r);
           int mid=l+r>>1;
           update(2*v,l,mid,x,y);
           update((2*v)+1,mid,r,x,y);
           seg[v]=seg[2*v]+seg[(2*v)+1];
           //cout<<seg[v]<<" "<<v<<endl;
           seg[v]%=mod;
}
int get(int v,int l,int r,int x,int y){
           if(y<=l||x>=r){
                      return 0;
           }
           else if(x<=l&&r<=y){
                      return seg[v];
           }
           shift(v,l,r);
           int mid=l+r>>1;
           long long int X=(get(2*v,l,mid,x,y)%mod)+(get(2*v+1,mid,r,x,y)%mid);
           seg[v]=seg[v*2]+seg[2*v+1];
           seg[v]%=mod;
           x%=mod;
           return X;
}
int main(){
	fibo[1]=1;
	fibo[2]=1;
	for(int i=3;i<=100000;i++){
		fibo[i]=fibo[i-1]+fibo[i-2];
		fibo[i]%=mod;
	}
     for(int i=1;i<=100000;i++){
     	fiboo[i]=fiboo[i-1]+fibo[i];
     	fiboo[i]%=mod;
	 }

	int n;
	int m;
	cin>>n>>m;
	for(int i=0;i<n;i++){
		cin>>bak[i];
	}
	build(1,0,n);
	while(m>0){
		m--;
		int g;
		cin>>g;
		if(g==2){
			int l;
			int r;
			cin>>l>>r;
			long long int f=get(1,0,n,l-1,r);
			f%=mod;
			cout<<f<<endl;
		}
		else{
			int l;
			int r;
			cin>>l>>r;
			update(1,0,n,l-1,r);
		}
	//	cout<<seg[3]<<endl;
	}
return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
long long int seg[4*maxn];
long long int lazy[4*maxn];
long long int lazy2[4*maxn];
long long int bak[4*maxn];
long long int fibo[4*maxn];
long long int fiboo[4*maxn];
int mod=1e9+9;
void build(int v,int l,int r){
	if(r-l==1){
		seg[v]=bak[l];
		seg[v]%=mod;
		return ;
	}
	int mid = l+r;
	mid /= 2;
	build(2*v,l,mid);
	build(2*v+1,mid,r);
	seg[v]=seg[2*v]+seg[2*v+1];
	seg[v]%=mod;
}
void shift(int v,int l,int r){
	if(lazy2[v]==0){
		return ;
	}
	int mid=l+r>>1;
	lazy[2*v]+=lazy[v];
	lazy[2*v]%=mod;
	lazy2[2*v]+=lazy2[v];
	lazy[2*v+1]%=mod;
	seg[2*v]+=(((1ll*lazy2[v]*(fiboo[mid-l-2]+1))%mod)+(1ll*lazy[v]*fiboo[mid-l-1])%mod)%mod;
	seg[2*v]%=mod;
	lazy[2*v+1]+=(((1ll*lazy2[v]*(fibo[mid-l]))%mod)+((1ll*lazy[v]*fibo[mid-l+1])%mod))%mod;
	lazy[2*v+1]%=mod;
	lazy2[2*v+1]+=(((1ll*lazy2[v]*(fibo[(mid-l)-1]))%mod)+((1ll*lazy[v]*fibo[mid-l])%mod))%mod;
	lazy2[2*v+1]%mod;
	long long int at=(((1ll*lazy2[v]*(fibo[mid-l]))%mod)+((1ll*lazy[v]*fibo[mid-l+1])%mod))%mod;
	long long int bak2=(((1ll*lazy2[v]*(fibo[(mid-l)-1]))%mod)+(((1ll*lazy[v]*fibo[mid-l])%mod)))%mod;
	seg[2*v+1]+=(((1ll*at*fiboo[r-mid-1])%mod)+((1ll*bak2*(fiboo[r-mid-2]+1))%mod))%mod;
	seg[2*v+1]%=mod;
	lazy[v]=0;
	lazy2[v]=0;
}
void update(int v,int l,int r,int x,int y){
           if(y<=l||x>=r){
           	//shift(v,l,r);
                      return;
           }
           else if(x<=l&&r<=y){
                      lazy[v]+=fibo[l-x+2];
                      lazy[v]%=mod;
                      lazy2[v]+=fibo[l-x+1];
                      lazy2[v]%=mod;
                      //cout<<lazy[v]<<" "<<lazy2[v]<<" "<<l<<" "<<r<<endl;
                      seg[v]+=(((1ll*fibo[l-x+2]*(fiboo[r-l-1]))%mod)+((1ll*fibo[l-x+1]*(fiboo[r-l-2]+1))%mod))%mod;
                      seg[v]%=mod;
                      //shift(v,l,r);
             //         cout<<seg[v]<<" "<<v<<endl;
             return ;
           }
                      shift(v,l,r);
           int mid=l+r>>1;
           update(2*v,l,mid,x,y);
           update((2*v)+1,mid,r,x,y);
           seg[v]=seg[2*v]+seg[(2*v)+1];
           //cout<<seg[v]<<" "<<v<<endl;
           seg[v]%=mod;
}
int get(int v,int l,int r,int x,int y){
           if(y<=l||x>=r){
                      return 0;
           }
           else if(x<=l&&r<=y){
                      return seg[v];
           }
           shift(v,l,r);
           int mid=l+r>>1;
           long long int X = get(2*v,l,mid,x,y) + get(2*v+1,mid,r,x,y);
           seg[v]=seg[v*2]+seg[2*v+1];
           seg[v]%=mod;
           x%=mod;
           return X;
}
int main(){
	fibo[1]=1;
	fibo[2]=1;
	for(int i=3;i<=100000;i++){
		fibo[i]=fibo[i-1]+fibo[i-2];
		fibo[i]%=mod;
	}
     for(int i=1;i<=100000;i++){
     	fiboo[i]=fiboo[i-1]+fibo[i];
     	fiboo[i]%=mod;
	 }

	int n;
	int m;
	cin>>n>>m;
	for(int i=0;i<n;i++){
		cin>>bak[i];
	}
	build(1,0,n);
	while(m>0){
		m--;
		int g;
		cin>>g;
		if(g==2){
			int l;
			int r;
			cin>>l>>r;
			long long int f=get(1,0,n,l-1,r);
			f%=mod;
			cout<<f<<endl;
		}
		else{
			int l;
			int r;
			cin>>l>>r;
			update(1,0,n,l-1,r);
		}
	//	cout<<seg[3]<<endl;
	}
return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
long long int seg[4*maxn];
long long int lazy[4*maxn];
long long int lazy2[4*maxn];
long long int bak[4*maxn];
long long int fibo[4*maxn];
long long int fiboo[4*maxn];
int mod=1e9+7;
void ok(long long int &k){
	if(k>=mod){
		k-=mod;
	}
	if(k<0){
		k+=mod;
	}
}
void build(int v,int l,int r){
	if(r-l==1){
		seg[v]=bak[l];
		ok(seg[v]);
		return ;
	}
	int mid = l+r;
	mid /= 2;
	build(2*v,l,mid);
	build(2*v+1,mid,r);
	seg[v]=seg[2*v]+seg[2*v+1];
	ok(seg[v]);
}
void shift(int v,int l,int r){
	if(lazy2[v]==0){
		return ;
	}
	int mid=l+r;
	mid/=2;
	lazy[2*v]+=lazy[v];
	ok(lazy[2*v]);
	lazy2[2*v]+=lazy2[v];
	ok(lazy2[2*v]);
	seg[2*v]+=(1ll*lazy2[v]*(fiboo[mid-l-2]+1))+(1ll*lazy[v]*fiboo[mid-l-1]);
	ok(seg[2*v]);
	lazy[2*v+1]+=(1ll*lazy2[v]*(fibo[mid-l]))+(1ll*lazy[v]*fibo[mid-l+1]);
	ok(lazy[2*v+1]);
	lazy2[2*v+1]+=(1ll*lazy2[v]*(fibo[(mid-l)-1]))+(1ll*lazy[v]*fibo[mid-l]);
	ok(lazy2[2*v+1]);
	long long int at=(1ll*lazy2[v]*(fibo[mid-l]))+(1ll*lazy[v]*fibo[mid-l+1]);
	ok(at);
	long long int bak2=(1ll*lazy2[v]*(fibo[(mid-l)-1]))+(1ll*lazy[v]*fibo[mid-l]);
	ok(bak2);
	seg[2*v+1]+=(1ll*at*fiboo[r-mid-1])+(1ll*bak2*(fiboo[r-mid-2]+1));
	ok(seg[2*v+1]);
	lazy[v]=0;
	lazy2[v]=0;
}
void update(int v,int l,int r,int x,int y){
           if(y<=l||x>=r){
           	//shift(v,l,r);
                      return;
           }
           else if(x<=l&&r<=y){
                      lazy[v]+=fibo[l-x+2];
                      ok(lazy[v]);
                      lazy2[v]+=fibo[l-x+1];
                      //cout<<lazy[v]<<" "<<lazy2[v]<<" "<<l<<" "<<r<<endl;
                      ok(lazy2[v]);
                      seg[v]+=(fibo[l-x+2]*(fiboo[r-l-1]))+(fibo[l-x+1]*(fiboo[r-l-2]+1));
                     ok(seg[v]);
                      //shift(v,l,r);
             //         cout<<seg[v]<<" "<<v<<endl;
             return ;
           }
                      shift(v,l,r);
           int mid=l+r;
           mid/=2;
           update(2*v,l,mid,x,y);
           update((2*v)+1,mid,r,x,y);
           seg[v]=seg[2*v]+seg[(2*v)+1];
           //cout<<seg[v]<<" "<<v<<endl;
           ok(seg[v]);
}
int get(int v,int l,int r,int x,int y){
           if(y<=l||x>=r){
                      return 0;
           }
           else if(x<=l&&r<=y){
                      return seg[v];
           }
           shift(v,l,r);
           int mid=l+r;
           mid/=2;
           long long int X = get(2*v,l,mid,x,y) + get(2*v+1,mid,r,x,y);
           seg[v]=seg[v*2]+seg[2*v+1];
           ok(X);
           return X;
}
int main(){
	fibo[1]=1;
	fibo[2]=1;
	for(int i=3;i<=100000;i++){
		fibo[i]=fibo[i-1]+fibo[i-2];
		ok(fibo[i]);
	}
     for(int i=1;i<=100000;i++){
     	fiboo[i]=fiboo[i-1]+fibo[i];
     	ok(fiboo[i]);
	 }

	int n;
	int m;
	cin>>n>>m;
	for(int i=0;i<n;i++){
		cin>>bak[i];
	}
	build(1,0,n);
	while(m>0){
		m--;
		int g;
		cin>>g;
		if(g==2){
			int l;
			int r;
			cin>>l>>r;
			cout<<get(1,0,n,l-1,r)<<endl;
		}
		else{
			int l;
			int r;
			cin>>l>>r;
			update(1,0,n,l-1,r);
		}
	//	cout<<seg[3]<<endl;
	}
return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
long long int seg[4*maxn];
long long int lazy[4*maxn];
long long int lazy2[4*maxn];
long long int bak[4*maxn];
long long int fibo[4*maxn];
long long int fiboo[4*maxn];
int mod=1e9+7;
void build(int v,int l,int r){
	if(r-l==1){
		seg[v]=bak[l];
		seg[v]%=mod;
		return ;
	}
	int mid = l+r;
	mid /= 2;
	build(2*v,l,mid);
	build(2*v+1,mid,r);
	seg[v]=seg[2*v]+seg[2*v+1];
	seg[v]%=mod;
}
void shift(int v,int l,int r){
	if(lazy2[v]==0){
		return ;
	}
	int mid=l+r>>1;
	lazy[2*v]+=lazy[v];
	lazy[2*v]%=mod;
	lazy2[2*v]+=lazy2[v];
	lazy[2*v+1]%=mod;
	seg[2*v]+=(((1ll*lazy2[v]*(fiboo[mid-l-2]+1))%mod)+(1ll*lazy[v]*fiboo[mid-l-1])%mod)%mod;
	lazy[2*v+1]+=(((1ll*lazy2[v]*(fibo[mid-l]))%mod)+((1ll*lazy[v]*fibo[mid-l+1])%mod))%mod;
	lazy2[2*v+1]+=(((1ll*lazy2[v]*(fibo[(mid-l)-1]))%mod)+((1ll*lazy[v]*fibo[mid-l])%mod))%mod;
	long long int at=(((1ll*lazy2[v]*(fibo[mid-l]))%mod)+((1ll*lazy[v]*fibo[mid-l+1])%mod))%mod;
	long long int bak2=(((1ll*lazy2[v]*(fibo[(mid-l)-1]))%mod)+(((1ll*lazy[v]*fibo[mid-l])%mod)))%mod;
	seg[2*v+1]+=(((1ll*at*fiboo[r-mid-1])%mod)+((1ll*bak2*(fiboo[r-mid-2]+1))%mod))%mod;
	lazy[v]=0;
	lazy2[v]=0;
}
void update(int v,int l,int r,int x,int y){
           if(y<=l||x>=r){
           	//shift(v,l,r);
                      return;
           }
           else if(x<=l&&r<=y){
                      lazy[v]+=fibo[l-x+2];
                      lazy[v]%=mod;
                      lazy2[v]+=fibo[l-x+1];
                      lazy2[v]%=mod;
                      //cout<<lazy[v]<<" "<<lazy2[v]<<" "<<l<<" "<<r<<endl;
                      seg[v]+=(((fibo[l-x+2]*(fiboo[r-l-1]))%mod)+((fibo[l-x+1]*(fiboo[r-l-2]+1))%mod))%mod;
                      //shift(v,l,r);
             //         cout<<seg[v]<<" "<<v<<endl;
             return ;
           }
                      shift(v,l,r);
           int mid=l+r>>1;
           update(2*v,l,mid,x,y);
           update((2*v)+1,mid,r,x,y);
           seg[v]=seg[2*v]+seg[(2*v)+1];
           //cout<<seg[v]<<" "<<v<<endl;
           seg[v]%=mod;
}
int get(int v,int l,int r,int x,int y){
           if(y<=l||x>=r){
                      return 0;
           }
           else if(x<=l&&r<=y){
                      return seg[v];
           }
           shift(v,l,r);
           int mid=l+r>>1;
           long long int X = get(2*v,l,mid,x,y) + get(2*v+1,mid,r,x,y);
           seg[v]=seg[v*2]+seg[2*v+1];
           seg[v]%=mod;
           x%=mod;
           return X;
}
int main(){
	fibo[1]=1;
	fibo[2]=1;
	for(int i=3;i<=100000;i++){
		fibo[i]=fibo[i-1]+fibo[i-2];
		fibo[i]%=mod;
	}
     for(int i=1;i<=100000;i++){
     	fiboo[i]=fiboo[i-1]+fibo[i];
     	fiboo[i]%=mod;
	 }

	int n;
	int m;
	cin>>n>>m;
	for(int i=0;i<n;i++){
		cin>>bak[i];
	}
	build(1,0,n);
	while(m>0){
		m--;
		int g;
		cin>>g;
		if(g==2){
			int l;
			int r;
			cin>>l>>r;
			long long int f=get(1,0,n,l-1,r);
			f%=mod;
			cout<<f<<endl;
		}
		else{
			int l;
			int r;
			cin>>l>>r;
			update(1,0,n,l-1,r);
		}
	//	cout<<seg[3]<<endl;
	}
return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
long long int seg[4*maxn];
long long int lazy[4*maxn];
long long int lazy2[4*maxn];
long long int bak[4*maxn];
long long int fibo[4*maxn];
long long int fiboo[4*maxn];
long long int mod=1e9+9;
void build(int v,int l,int r){
	if(r-l==1){
		seg[v]=bak[l];
		seg[v]%=mod;
		return ;
	}
	int mid = l+r;
	mid /= 2;
	build(2*v,l,mid);
	build(2*v+1,mid,r);
	seg[v]=seg[2*v]+seg[2*v+1];
	seg[v]%=mod;
}
void shift(int v,int l,int r){
	if(lazy2[v]==0){
		return ;
	}
	int mid=l+r>>1;
	lazy[2*v]+=lazy[v];
	lazy[2*v]%=mod;
	lazy2[2*v]+=lazy2[v];
	lazy[2*v+1]%=mod;
	seg[2*v]+=(((1ll*lazy2[v]*(fiboo[mid-l-2]+1))%mod)+(1ll*lazy[v]*fiboo[mid-l-1])%mod)%mod;
	seg[2*v]%=mod;
	lazy[2*v+1]+=(((1ll*lazy2[v]*(fibo[mid-l]))%mod)+((1ll*lazy[v]*fibo[mid-l+1])%mod))%mod;
	lazy[2*v+1]%=mod;
	lazy2[2*v+1]+=(((1ll*lazy2[v]*(fibo[(mid-l)-1]))%mod)+((1ll*lazy[v]*fibo[mid-l])%mod))%mod;
	lazy2[2*v+1]%=mod;
	long long int at=(((1ll*lazy2[v]*(fibo[mid-l]))%mod)+((1ll*lazy[v]*fibo[mid-l+1])%mod))%mod;
	long long int bak2=(((1ll*lazy2[v]*(fibo[(mid-l)-1]))%mod)+(((1ll*lazy[v]*fibo[mid-l])%mod)))%mod;
	seg[2*v+1]+=(((1ll*at*fiboo[r-mid-1])%mod)+((1ll*bak2*(fiboo[r-mid-2]+1))%mod))%mod;
	seg[2*v+1]%=mod;
	lazy[v]=0;
	lazy2[v]=0;
}
void update(int v,int l,int r,int x,int y){
           if(y<=l||x>=r){
           	//shift(v,l,r);
                      return;
           }
           else if(x<=l&&r<=y){
                      lazy[v]+=fibo[l-x+2];
                      lazy[v]%=mod;
                      lazy2[v]+=fibo[l-x+1];
                      lazy2[v]%=mod;
                      //cout<<lazy[v]<<" "<<lazy2[v]<<" "<<l<<" "<<r<<endl;
                      seg[v]+=(((1ll*fibo[l-x+2]*(fiboo[r-l-1]))%mod)+((1ll*fibo[l-x+1]*(fiboo[r-l-2]+1))%mod))%mod;
                      seg[v]%=mod;
                      //shift(v,l,r);
             //         cout<<seg[v]<<" "<<v<<endl;
             return ;
           }
                      shift(v,l,r);
           int mid=l+r>>1;
           update(2*v,l,mid,x,y);
           update((2*v)+1,mid,r,x,y);
           seg[v]=seg[2*v]+seg[(2*v)+1];
           //cout<<seg[v]<<" "<<v<<endl;
           seg[v]%=mod;
}
int get(int v,int l,int r,int x,int y){
           if(y<=l||x>=r){
                      return 0;
           }
           else if(x<=l&&r<=y){
                      return seg[v];
           }
           shift(v,l,r);
           int mid=l+r>>1;
           long long int X=get(2*v,l,mid,x,y)+get(2*v+1,mid,r,x,y);
           seg[v]=seg[v*2]+seg[2*v+1];
           seg[v]%=mod;
           x%=mod;
           return X;
}
int main(){
	fibo[1]=1;
	fibo[2]=1;
	for(int i=3;i<=100000;i++){
		fibo[i]=fibo[i-1]+fibo[i-2];
		fibo[i]%=mod;
	}
     for(int i=1;i<=100000;i++){
     	fiboo[i]=fiboo[i-1]+fibo[i];
     	fiboo[i]%=mod;
	 }

	int n;
	int m;
	cin>>n>>m;
	for(int i=0;i<n;i++){
		cin>>bak[i];
	}
	build(1,0,n);
	while(m>0){
		m--;
		int g;
		cin>>g;
		if(g==2){
			int l;
			int r;
			cin>>l>>r;
			long long int f=get(1,0,n,l-1,r);
			f%=mod;
			cout<<f<<endl;
		}
		else{
			int l;
			int r;
			cin>>l>>r;
			update(1,0,n,l-1,r);
		}
	//	cout<<seg[3]<<endl;
	}
return 0;
}


//be nam KHODA
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
long long int seg[4*maxn];
long long int lazy[4*maxn];
long long int lazy2[4*maxn];
long long int bak[4*maxn];
long long int fibo[4*maxn];
long long int fiboo[4*maxn];
const long long int mod=1e9+9;
void build(int v,int l,int r){
	if(r-l==1){
		seg[v]=bak[l];
		seg[v]%=mod;
		return ;
	}
	long long int mid = l+r>>1;
	build(2*v,l,mid);
	build(2*v+1,mid,r);
	seg[v]=seg[2*v]+seg[2*v+1];
	seg[v]%=mod;
}
void shift(int v,int l,int r){
	if(lazy2[v]==0){
		return ;
	}
	long long int mid=l+r>>1;
	lazy[2*v]+=lazy[v];
	lazy[2*v]%=mod;
	lazy2[2*v]+=lazy2[v];
	lazy[2*v+1]%=mod;
	long long int at=lazy[v]%mod;
	long long int bak2=lazy2[v]%mod;
	seg[2*v]+=(((1ll*bak2*(fiboo[mid-l-2]+1))%mod)+(1ll*at*fiboo[mid-l-1])%mod);
	seg[2*v]%=mod;
	lazy[2*v+1]+=(((1ll*bak2*(fibo[mid-l]))%mod)+((1ll*at*fibo[mid-l+1])%mod));
	lazy[2*v+1]%=mod;
	lazy2[2*v+1]+=(((1ll*bak2*(fibo[(mid-l)-1]))%mod)+((1ll*at*fibo[mid-l])%mod));
	lazy2[2*v+1]%=mod;
	long long int d=at;
	d%=mod;
	at=(((1ll*bak2*(fibo[mid-l]))%mod)+((1ll*at*fibo[mid-l+1])%mod));
	at%=mod;
	bak2=(((1ll*bak2*(fibo[(mid-l)-1]))%mod)+(((1ll*d*fibo[mid-l])%mod)));
	bak2%=mod;
	seg[2*v+1]+=(((1ll*at*fiboo[r-mid-1])%mod)+((1ll*bak2*(fiboo[r-mid-2]+1))%mod));
	seg[2*v+1]%=mod;
	lazy[v]=0;
	lazy2[v]=0;
}
void update(int v,int l,int r,int x,int y){
           if(y<=l||x>=r){
           	//shift(v,l,r);
                      return;
           }
           else if(x<=l&&r<=y){
                      lazy[v]+=fibo[l-x+2];
                      lazy[v]%=mod;
                      lazy2[v]+=fibo[l-x+1];
                      lazy2[v]%=mod;
                      //cout<<lazy[v]<<" "<<lazy2[v]<<" "<<l<<" "<<r<<endl;
                      seg[v]+=(((1ll*fibo[l-x+2]*(fiboo[r-l-1]))%mod)+((1ll*fibo[l-x+1]*(fiboo[r-l-2]+1))%mod));
                      seg[v]%=mod;
                      //shift(v,l,r);
             //         cout<<seg[v]<<" "<<v<<endl;
             return ;
           }
                      shift(v,l,r);
           long long int mid=l+r>>1;
           update(2*v,l,mid,x,y);
           update((2*v)+1,mid,r,x,y);
           seg[v]=seg[2*v]+seg[(2*v)+1];
           //cout<<seg[v]<<" "<<v<<endl;
           seg[v]%=mod;
}
long long int get(int v,int l,int r,int x,int y){
           if(y<=l||x>=r){
                      return 0;
           }
           else if(x<=l&&r<=y){
                      return seg[v];
           }
           shift(v,l,r);
           long long int mid=l+r>>1;
           long long int X=get(2*v,l,mid,x,y)+get(2*v+1,mid,r,x,y);
           seg[v]=seg[v*2]+seg[2*v+1];
           seg[v]%=mod;
           X%=mod;
           return X;
}
int main(){
	fibo[1]=1;
	fibo[2]=1;
	for(int i=3;i<=100000;i++){
		fibo[i]=fibo[i-1]+fibo[i-2];
		fibo[i]%=mod;
	}
     for(int i=1;i<=100000;i++){
     	fiboo[i]=fiboo[i-1]+fibo[i];
     	fiboo[i]%=mod;
	 }

	int n;
	int m;
	cin>>n>>m;
	for(int i=0;i<n;i++){
		cin>>bak[i];
	}
	build(1,0,n);
	while(m>0){
		m--;
		int g;
		cin>>g;
		if(g==2){
			int l;
			int r;
			cin>>l>>r;
			long long int f=get(1,0,n,l-1,r);
			f%=mod;
			cout<<f<<endl;
		}
		else{
			int l;
			int r;
			cin>>l>>r;
			update(1,0,n,l-1,r);
		}
	//	cout<<seg[3]<<endl;
	}
return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
long long int seg[4*maxn];
long long int lazy[4*maxn];
long long int lazy2[4*maxn];
long long int bak[4*maxn];
long long int fibo[4*maxn];
long long int fiboo[4*maxn];
long long int mod=1e9+9;
void build(int v,int l,int r){
	if(r-l==1){
		seg[v]=bak[l];
		seg[v]%=mod;
		return ;
	}
	int mid = l+r;
	mid /= 2;
	build(2*v,l,mid);
	build(2*v+1,mid,r);
	seg[v]=seg[2*v]+seg[2*v+1];
	seg[v]%=mod;
}
void shift(int v,int l,int r){
	if(lazy2[v]==0){
		return ;
	}
	int mid=l+r>>1;
	lazy[2*v]+=lazy[v];
	lazy[2*v]%=mod;
	lazy2[2*v]+=lazy2[v];
	lazy[2*v+1]%=mod;
	seg[2*v]+=(((1ll*lazy2[v]*(fiboo[mid-l-2]+1))%mod)+(1ll*lazy[v]*fiboo[mid-l-1])%mod)%mod;
	seg[2*v]%=mod;
	lazy[2*v+1]+=(((1ll*lazy2[v]*(fibo[mid-l]))%mod)+((1ll*lazy[v]*fibo[mid-l+1])%mod))%mod;
	lazy[2*v+1]%=mod;
	lazy2[2*v+1]+=(((1ll*lazy2[v]*(fibo[(mid-l)-1]))%mod)+((1ll*lazy[v]*fibo[mid-l])%mod))%mod;
	lazy2[2*v+1]%=mod;
	long long int at=(((1ll*lazy2[v]*(fibo[mid-l]))%mod)+((1ll*lazy[v]*fibo[mid-l+1])%mod))%mod;
	long long int bak2=(((1ll*lazy2[v]*(fibo[(mid-l)-1]))%mod)+(((1ll*lazy[v]*fibo[mid-l])%mod)))%mod;
	seg[2*v+1]+=(((1ll*at*fiboo[r-mid-1])%mod)+((1ll*bak2*(fiboo[r-mid-2]+1))%mod))%mod;
	seg[2*v+1]%=mod;
	lazy[v]=0;
	lazy2[v]=0;
}
void update(int v,int l,int r,int x,int y){
           if(y<=l||x>=r){
           	//shift(v,l,r);
                      return;
           }
           else if(x<=l&&r<=y){
                      lazy[v]+=fibo[l-x+2];
                      lazy[v]%=mod;
                      lazy2[v]+=fibo[l-x+1];
                      lazy2[v]%=mod;
                      //cout<<lazy[v]<<" "<<lazy2[v]<<" "<<l<<" "<<r<<endl;
                      seg[v]+=(((1ll*fibo[l-x+2]*(fiboo[r-l-1]))%mod)+((1ll*fibo[l-x+1]*(fiboo[r-l-2]+1))%mod))%mod;
                      seg[v]%=mod;
                      //shift(v,l,r);
             //         cout<<seg[v]<<" "<<v<<endl;
             return ;
           }
                      shift(v,l,r);
           int mid=l+r>>1;
           update(2*v,l,mid,x,y);
           update((2*v)+1,mid,r,x,y);
           seg[v]=seg[2*v]+seg[(2*v)+1];
           //cout<<seg[v]<<" "<<v<<endl;
           seg[v]%=mod;
}
long long int get(int v,int l,int r,int x,int y){
           if(y<=l||x>=r){
                      return 0;
           }
           else if(x<=l&&r<=y){
                      return seg[v];
           }
           shift(v,l,r);
           int mid=l+r>>1;
           long long int X=get(2*v,l,mid,x,y)+get(2*v+1,mid,r,x,y);
           seg[v]=seg[v*2]+seg[2*v+1];
           seg[v]%=mod;
           x%=mod;
           return X;
}
int main(){
	fibo[1]=1;
	fibo[2]=1;
	for(int i=3;i<=100000;i++){
		fibo[i]=fibo[i-1]+fibo[i-2];
		fibo[i]%=mod;
	}
     for(int i=1;i<=100000;i++){
     	fiboo[i]=fiboo[i-1]+fibo[i];
     	fiboo[i]%=mod;
	 }

	int n;
	int m;
	cin>>n>>m;
	for(int i=0;i<n;i++){
		cin>>bak[i];
	}
	build(1,0,n);
	while(m>0){
		m--;
		int g;
		cin>>g;
		if(g==2){
			int l;
			int r;
			cin>>l>>r;
			long long int f=get(1,0,n,l-1,r);
			f%=mod;
			cout<<f<<endl;
		}
		else{
			int l;
			int r;
			cin>>l>>r;
			update(1,0,n,l-1,r);
		}
	//	cout<<seg[3]<<endl;
	}
return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 300005,P = 1000000009;
using ll = long long;
//Sqrt(5) === 383008016
const int S5D5 = 276601605,Q1 = 691504013,Q2 = 308495997;
//Q1=(1+Sqrt(5))/2,Q2=(1-Sqrt(5))/2,S5D5=Sqrt(5)/5
//Fn=S5D5(Q1^n-Q2^n) inv(Q1-1)=Q1,inv(Q2-2)=Q2
int n,m,a[N];
struct TNode{int l,r;ll v;} t[N << 2];
ll tg1[N << 2],tg2[N << 2],pw1[N],pw2[N];
inline int lc(int pos) {return pos << 1;}
inline int rc(int pos) {return pos << 1 | 1;}
inline void pushup(int pos) {t[pos].v = (t[lc(pos)].v + t[rc(pos)].v) % P;}
void build(int pos,int l,int r)
{
    t[pos].l = l;t[pos].r = r;
    if (l == r) {t[pos].v = a[l];return;}
    int mid = (l + r) >> 1;
    build(lc(pos),l,mid);build(rc(pos),mid + 1,r);
    pushup(pos);
}
inline void add(int pos,ll a,ll b)
{
    tg1[pos] = (tg1[pos] + a) % P;tg2[pos] = (tg2[pos] + b) % P;
    ll &r = t[pos].v;int len = t[pos].r - t[pos].l + 1;
    r = (r + a * (pw1[len] - 1) % P * Q1 % P) % P;
    r = (r - b * (pw2[len] - 1) % P * Q2 % P + P) % P;
}
inline void pushdown(int pos)
{
    int mid = (t[pos].l + t[pos].r) >> 1;
    add(lc(pos),tg1[pos],tg2[pos]);
    add(rc(pos),tg1[pos] * pw1[mid - t[pos].l + 1] % P,
        tg2[pos] * pw2[mid - t[pos].l + 1] % P);
    tg1[pos] = tg2[pos] = 0;
}
void modify(int pos,int l,int r,int v)
{
    if (t[pos].l == l && t[pos].r == r)
    {
        add(pos,S5D5 * pw1[l - v + 1] % P,S5D5 * pw2[l - v + 1] % P);
        return;
    }
    pushdown(pos);
    int mid = (t[pos].l + t[pos].r) >> 1;
    if (r <= mid) modify(lc(pos),l,r,v);
    else if (l > mid) modify(rc(pos),l,r,v);
    else modify(lc(pos),l,mid,v),modify(rc(pos),mid + 1,r,v);
    pushup(pos);
}
ll query(int pos,int l,int r)
{
    if (t[pos].l == l && t[pos].r == r) return t[pos].v;
    int mid = (t[pos].l + t[pos].r) >> 1;
    pushdown(pos);
    if (r <= mid) return query(lc(pos),l,r);
    else if (l > mid) return query(rc(pos),l,r);
    else return (query(lc(pos),l,mid) + query(rc(pos),mid + 1,r)) % P;
}
int main ()
{
    ios::sync_with_stdio(false);
    cin >> n >> m;
    for (int i = 1;i <= n;i++) cin >> a[i];
    pw1[0] = pw2[0] = 1;
    for (int i = 1;i <= n;i++)
    {
        pw1[i] = pw1[i - 1] * Q1 % P;pw2[i] = pw2[i - 1] * Q2 % P;
    }
    build(1,1,n);
    int t1,t2,t3;
    for (int i = 1;i <= m;i++)
    {
        cin >> t1 >> t2 >> t3;
        if (t1 == 1) modify(1,t2,t3,t2);
        else cout << query(1,t2,t3) << endl;
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 300005,P = 1000000009;
using ll = long long;
//Sqrt(5) === 383008016
const int S5D5 = 276601605,Q1 = 691504013,Q2 = 308495997;
//Q1=(1+Sqrt(5))/2,Q2=(1-Sqrt(5))/2,S5D5=Sqrt(5)/5
//Fn=S5D5(Q1^n-Q2^n) inv(Q1-1)=Q1,inv(Q2-2)=Q2
int n,m,a[N];
struct TNode{int l,r;ll v;} t[N << 2];
ll tg1[N],tg2[N],pw1[N],pw2[N];
inline int lc(int pos) {return pos << 1;}
inline int rc(int pos) {return pos << 1 | 1;}
inline void pushup(int pos) {t[pos].v = (t[lc(pos)].v + t[rc(pos)].v) % P;}
void build(int pos,int l,int r)
{
    t[pos].l = l;t[pos].r = r;
    if (l == r) {t[pos].v = a[l];return;}
    int mid = (l + r) >> 1;
    build(lc(pos),l,mid);build(rc(pos),mid + 1,r);
    pushup(pos);
}
inline void add(int pos,ll a,ll b)
{
    tg1[pos] = (tg1[pos] + a) % P;tg2[pos] = (tg2[pos] + b) % P;
    ll &r = t[pos].v;int len = t[pos].r - t[pos].l + 1;
    r += a * (pw1[len] - 1) % P * Q1 % P;
    r -= b * (pw2[len] - 1) % P * Q2 % P;
    r = (r % P + P) % P;
}
inline void pushdown(int pos)
{
    int mid = (t[pos].l + t[pos].r) >> 1;
    add(lc(pos),tg1[pos],tg2[pos]);
    add(rc(pos),tg1[pos] * pw1[mid - t[pos].l + 1] % P,
        tg2[pos] * pw2[mid - t[pos].l + 1] % P);
    tg1[pos] = tg2[pos] = 0;
}
void modify(int pos,int l,int r,int v)
{
    if (t[pos].l == l && t[pos].r == r)
    {
        add(pos,S5D5 * pw1[l - v + 1] % P,S5D5 * pw2[l - v + 1] % P);
        return;
    }
    pushdown(pos);
    int mid = (t[pos].l + t[pos].r) >> 1;
    if (r <= mid) modify(lc(pos),l,r,v);
    else if (l > mid) modify(rc(pos),l,r,v);
    else modify(lc(pos),l,mid,v),modify(rc(pos),mid + 1,r,v);
    pushup(pos);
}
ll query(int pos,int l,int r)
{
    if (t[pos].l == l && t[pos].r == r) return t[pos].v;
    int mid = (t[pos].l + t[pos].r) >> 1;
    pushdown(pos);
    if (r <= mid) return query(lc(pos),l,r);
    else if (l > mid) return query(rc(pos),l,r);
    else return (query(lc(pos),l,mid) + query(rc(pos),mid + 1,r)) % P;
}
int main ()
{
    ios::sync_with_stdio(false);
    cin >> n >> m;
    for (int i = 1;i <= n;i++) cin >> a[i];
    pw1[0] = pw2[0] = 1;
    for (int i = 1;i <= n;i++)
    {
        pw1[i] = pw1[i - 1] * Q1 % P;pw2[i] = pw2[i - 1] * Q2 % P;
    }
    build(1,1,n);
    int t1,t2,t3;
    for (int i = 1;i <= m;i++)
    {
        cin >> t1 >> t2 >> t3;
        if (t1 == 1) modify(1,t2,t3,t2);
        else printf("%lld\n",query(1,t2,t3));
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 300005,P = 1000000009;
using ll = long long;
//Sqrt(5) === 383008016
const int S5D5 = 276601605,Q1 = 691504013,Q2 = 308495997;
//Q1=(1+Sqrt(5))/2,Q2=(1-Sqrt(5))/2,S5D5=Sqrt(5)/5
//Fn=S5D5(Q1^n-Q2^n) inv(Q1-1)=Q1,inv(Q2-2)=Q2
int n,m,a[N];
struct TNode{int l,r;ll v;} t[N << 2];
ll tg1[N],tg2[N],pw1[N],pw2[N];
inline int lc(int pos) {return pos << 1;}
inline int rc(int pos) {return pos << 1 | 1;}
inline void pushup(int pos) {t[pos].v = (t[lc(pos)].v + t[rc(pos)].v) % P;}
void build(int pos,int l,int r)
{
    t[pos].l = l;t[pos].r = r;
    if (l == r) {t[pos].v = a[l];return;}
    int mid = (l + r) >> 1;
    build(lc(pos),l,mid);build(rc(pos),mid + 1,r);
    pushup(pos);
}
inline void add(int pos,ll a,ll b)
{
    tg1[pos] = (tg1[pos] + a) % P;tg2[pos] = (tg2[pos] + b) % P;
    ll &r = t[pos].v;int len = t[pos].r - t[pos].l + 1;
    r += a * (-pw1[len] + 1 + P) % P * 308495996 % P;
    r -= b * (-pw2[len] + 1 + P) % P * 691504012 % P;
    r = (r % P + P) % P;
}
inline void pushdown(int pos)
{
    int mid = (t[pos].l + t[pos].r) >> 1;
    add(lc(pos),tg1[pos],tg2[pos]);
    add(rc(pos),tg1[pos] * pw1[mid - t[pos].l + 1] % P,
        tg2[pos] * pw2[mid - t[pos].l + 1] % P);
    tg1[pos] = tg2[pos] = 0;
}
void modify(int pos,int l,int r,int v)
{
    if (t[pos].l == l && t[pos].r == r)
    {
        add(pos,S5D5 * pw1[l - v + 1] % P,S5D5 * pw2[l - v + 1] % P);
        return;
    }
    pushdown(pos);
    int mid = (t[pos].l + t[pos].r) >> 1;
    if (r <= mid) modify(lc(pos),l,r,v);
    else if (l > mid) modify(rc(pos),l,r,v);
    else modify(lc(pos),l,mid,v),modify(rc(pos),mid + 1,r,v);
    pushup(pos);
}
ll query(int pos,int l,int r)
{
    if (t[pos].l == l && t[pos].r == r) return t[pos].v;
    int mid = (t[pos].l + t[pos].r) >> 1;
    pushdown(pos);
    if (r <= mid) return query(lc(pos),l,r);
    else if (l > mid) return query(rc(pos),l,r);
    else return (query(lc(pos),l,mid) + query(rc(pos),mid + 1,r)) % P;
}
int main ()
{
    ios::sync_with_stdio(false);
    cin >> n >> m;
    for (int i = 1;i <= n;i++) cin >> a[i];
    pw1[0] = pw2[0] = 1;
    for (int i = 1;i <= n;i++)
    {
        pw1[i] = pw1[i - 1] * Q1 % P;pw2[i] = pw2[i - 1] * Q2 % P;
    }
    build(1,1,n);
    int t1,t2,t3;
    for (int i = 1;i <= m;i++)
    {
        cin >> t1 >> t2 >> t3;
        if (t1 == 1) modify(1,t2,t3,t2);
        else cout << query(1,t2,t3) << endl;
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 300005,P = 1000000009;
using ll = long long;
//Sqrt(5) === 383008016
const int S5D5 = 276601605,Q1 = 691504013,Q2 = 308495997;
//Q1=(1+Sqrt(5))/2,Q2=(1-Sqrt(5))/2,S5D5=Sqrt(5)/5
//Fn=S5D5(Q1^n-Q2^n) inv(Q1-1)=Q1,inv(Q2-2)=Q2
int n,m,a[N];
struct TNode{int l,r;ll v;} t[N << 2];
ll tg1[N],tg2[N],pw1[N],pw2[N];
inline int lc(int pos) {return pos << 1;}
inline int rc(int pos) {return pos << 1 | 1;}
inline void pushup(int pos) {t[pos].v = (t[lc(pos)].v + t[rc(pos)].v) % P;}
void build(int pos,int l,int r)
{
    t[pos].l = l;t[pos].r = r;
    if (l == r) {t[pos].v = a[l];return;}
    int mid = (l + r) >> 1;
    build(lc(pos),l,mid);build(rc(pos),mid + 1,r);
    pushup(pos);
}
inline void add(int pos,ll a,ll b)
{
    tg1[pos] = (tg1[pos] + a) % P;tg2[pos] = (tg2[pos] + b) % P;
    ll &r = t[pos].v;int len = t[pos].r - t[pos].l + 1;
    r = (r + a * (pw1[len] - 1) % P * Q1 % P) % P;
    r = (r - b * (pw2[len] - 1) % P * Q2 % P + P) % P;
}
inline void pushdown(int pos)
{
    int mid = (t[pos].l + t[pos].r) >> 1;
    add(lc(pos),tg1[pos],tg2[pos]);
    add(rc(pos),tg1[pos] * pw1[mid - t[pos].l + 1] % P,
        tg2[pos] * pw2[mid - t[pos].l + 1] % P);
    tg1[pos] = tg2[pos] = 0;
}
void modify(int pos,int l,int r,int v)
{
    if (t[pos].l == l && t[pos].r == r)
    {
        add(pos,S5D5 * pw1[l - v + 1] % P,S5D5 * pw2[l - v + 1] % P);
        return;
    }
    pushdown(pos);
    int mid = (t[pos].l + t[pos].r) >> 1;
    if (r <= mid) modify(lc(pos),l,r,v);
    else if (l > mid) modify(rc(pos),l,r,v);
    else modify(lc(pos),l,mid,v),modify(rc(pos),mid + 1,r,v);
    pushup(pos);
}
ll query(int pos,int l,int r)
{
    if (t[pos].l == l && t[pos].r == r) return t[pos].v;
    int mid = (t[pos].l + t[pos].r) >> 1;
    pushdown(pos);
    if (r <= mid) return query(lc(pos),l,r);
    else if (l > mid) return query(rc(pos),l,r);
    else return (query(lc(pos),l,mid) + query(rc(pos),mid + 1,r)) % P;
}
int main ()
{
    ios::sync_with_stdio(false);
    cin >> n >> m;
    for (int i = 1;i <= n;i++) cin >> a[i];
    pw1[0] = pw2[0] = 1;
    for (int i = 1;i <= n;i++)
    {
        pw1[i] = pw1[i - 1] * Q1 % P;pw2[i] = pw2[i - 1] * Q2 % P;
    }
    build(1,1,n);
    int t1,t2,t3;
    for (int i = 1;i <= m;i++)
    {
        cin >> t1 >> t2 >> t3;
        if (t1 == 1) modify(1,t2,t3,t2);
        else cout << query(1,t2,t3) << endl;
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 300005,P = 1000000009;
using ll = long long;
//Sqrt(5) === 383008016
const int S5D5 = 276601605,Q1 = 691504013,Q2 = 308495997;
//Q1=(1+Sqrt(5))/2,Q2=(1-Sqrt(5))/2,S5D5=Sqrt(5)/5
//Fn=S5D5(Q1^n-Q2^n) inv(Q1-1)=Q1,inv(Q2-1)=Q2
int n,m,a[N];
struct TNode{int l,r;ll v;} t[N << 2];
ll tg1[N << 2],tg2[N << 2],pw1[N],pw2[N];
inline int lc(int pos) {return pos << 1;}
inline int rc(int pos) {return pos << 1 | 1;}
inline void pushup(int pos) {t[pos].v = (t[lc(pos)].v + t[rc(pos)].v) % P;}
void build(int pos,int l,int r)
{
    t[pos].l = l;t[pos].r = r;
    if (l == r) {t[pos].v = a[l];return;}
    int mid = (l + r) >> 1;
    build(lc(pos),l,mid);build(rc(pos),mid + 1,r);
    pushup(pos);
}
inline void add(int pos,ll a,ll b)
{
    tg1[pos] = (tg1[pos] + a) % P;tg2[pos] = (tg2[pos] + b) % P;
    ll &r = t[pos].v;int len = t[pos].r - t[pos].l + 1;
    r = (r + a * (pw1[len] - 1) % P * Q1 % P) % P;
    r = (r - b * (pw2[len] - 1) % P * Q2 % P + P) % P;
}
inline void pushdown(int pos)
{
    int mid = (t[pos].l + t[pos].r) >> 1;
    add(lc(pos),tg1[pos],tg2[pos]);
    add(rc(pos),tg1[pos] * pw1[mid - t[pos].l + 1] % P,
        tg2[pos] * pw2[mid - t[pos].l + 1] % P);
    tg1[pos] = tg2[pos] = 0;
}
void modify(int pos,int l,int r,int v)
{
    if (t[pos].l == l && t[pos].r == r)
    {
        add(pos,S5D5 * pw1[l - v + 1] % P,S5D5 * pw2[l - v + 1] % P);
        return;
    }
    pushdown(pos);
    int mid = (t[pos].l + t[pos].r) >> 1;
    if (r <= mid) modify(lc(pos),l,r,v);
    else if (l > mid) modify(rc(pos),l,r,v);
    else modify(lc(pos),l,mid,v),modify(rc(pos),mid + 1,r,v);
    pushup(pos);
}
ll query(int pos,int l,int r)
{
    if (t[pos].l == l && t[pos].r == r) return t[pos].v;
    int mid = (t[pos].l + t[pos].r) >> 1;
    pushdown(pos);
    if (r <= mid) return query(lc(pos),l,r);
    else if (l > mid) return query(rc(pos),l,r);
    else return (query(lc(pos),l,mid) + query(rc(pos),mid + 1,r)) % P;
}
int main ()
{
    ios::sync_with_stdio(false);
    cin >> n >> m;
    for (int i = 1;i <= n;i++) cin >> a[i];
    pw1[0] = pw2[0] = 1;
    for (int i = 1;i <= n;i++)
    {
        pw1[i] = pw1[i - 1] * Q1 % P;pw2[i] = pw2[i - 1] * Q2 % P;
    }
    build(1,1,n);
    int t1,t2,t3;
    for (int i = 1;i <= m;i++)
    {
        cin >> t1 >> t2 >> t3;
        if (t1 == 1) modify(1,t2,t3,t2);
        else cout << query(1,t2,t3) << endl;
    }
    return 0;
}


#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 300005,P = 1000000009;
using ll = long long;
//Sqrt(5) === 383008016
const int S5D5 = 276601605,Q1 = 691504013,Q2 = 308495997;
//Q1=(1+Sqrt(5))/2,Q2=(1-Sqrt(5))/2,S5D5=Sqrt(5)/5
//Fn=S5D5(Q1^n-Q2^n) inv(Q1-1)=Q1,inv(Q2-2)=Q2
int n,m,a[N];
struct TNode{int l,r;ll v;} t[N << 2];
ll tg1[N],tg2[N],pw1[N],pw2[N];
inline int lc(int pos) {return pos << 1;}
inline int rc(int pos) {return pos << 1 | 1;}
inline void pushup(int pos) {t[pos].v = (t[lc(pos)].v + t[rc(pos)].v) % P;}
void build(int pos,int l,int r)
{
    t[pos].l = l;t[pos].r = r;
    if (l == r) {t[pos].v = a[l];return;}
    int mid = (l + r) >> 1;
    build(lc(pos),l,mid);build(rc(pos),mid + 1,r);
    pushup(pos);
}
inline void add(int pos,ll a,ll b)
{
    tg1[pos] = (tg1[pos] + a) % P;tg2[pos] = (tg2[pos] + b) % P;
    ll &r = t[pos].v;int len = t[pos].r - t[pos].l + 1;
    r += a * (pw1[len] - 1) % P * Q1 % P;
    r -= b * (pw2[len] - 1) % P * Q2 % P;
    r = (r % P + P) % P;
}
inline void pushdown(int pos)
{
    int mid = (t[pos].l + t[pos].r) >> 1;
    add(lc(pos),tg1[pos],tg2[pos]);
    add(rc(pos),tg1[pos] * pw1[mid - t[pos].l + 1] % P,
        tg2[pos] * pw2[mid - t[pos].l + 1] % P);
    tg1[pos] = tg2[pos] = 0;
}
void modify(int pos,int l,int r,int v)
{
    if (t[pos].l == l && t[pos].r == r)
    {
        add(pos,S5D5 * pw1[l - v + 1] % P,S5D5 * pw2[l - v + 1] % P);
        return;
    }
    pushdown(pos);
    int mid = (t[pos].l + t[pos].r) >> 1;
    if (r <= mid) modify(lc(pos),l,r,v);
    else if (l > mid) modify(rc(pos),l,r,v);
    else modify(lc(pos),l,mid,v),modify(rc(pos),mid + 1,r,v);
    pushup(pos);
}
ll query(int pos,int l,int r)
{
    if (t[pos].l == l && t[pos].r == r) return t[pos].v;
    int mid = (t[pos].l + t[pos].r) >> 1;
    pushdown(pos);
    if (r <= mid) return query(lc(pos),l,r);
    else if (l > mid) return query(rc(pos),l,r);
    else return (query(lc(pos),l,mid) + query(rc(pos),mid + 1,r)) % P;
}
signed main ()
{
    ios::sync_with_stdio(false);
    cin >> n >> m;
    for (int i = 1;i <= n;i++) cin >> a[i];
    pw1[0] = pw2[0] = 1;
    for (int i = 1;i <= n;i++)
    {
        pw1[i] = pw1[i - 1] * Q1 % P;pw2[i] = pw2[i - 1] * Q2 % P;
    }
    build(1,1,n);
    int t1,t2,t3;
    for (int i = 1;i <= m;i++)
    {
        cin >> t1 >> t2 >> t3;
        if (t1 == 1) modify(1,t2,t3,t2);
        else cout << query(1,t2,t3) << endl;
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 300005,P = 1000000009;
using ll = long long;
//Sqrt(5) === 383008016
const int S5D5 = 276601605,Q1 = 691504013,Q2 = 308495997;
//Q1=(1+Sqrt(5))/2,Q2=(1-Sqrt(5))/2,S5D5=Sqrt(5)/5
//Fn=S5D5(Q1^n-Q2^n) inv(Q1-1)=Q1,inv(Q2-2)=Q2
int n,m,a[N];
struct TNode{int l,r;ll v;} t[N << 2];
ll tg1[N],tg2[N],pw1[N],pw2[N];
inline int lc(int pos) {return pos << 1;}
inline int rc(int pos) {return pos << 1 | 1;}
inline void pushup(int pos) {t[pos].v = (t[lc(pos)].v + t[rc(pos)].v) % P;}
void build(int pos,int l,int r)
{
    t[pos].l = l;t[pos].r = r;
    if (l == r) {t[pos].v = a[l];return;}
    int mid = (l + r) >> 1;
    build(lc(pos),l,mid);build(rc(pos),mid + 1,r);
    pushup(pos);
}
inline void add(int pos,ll a,ll b)
{
    tg1[pos] = (tg1[pos] + a) % P;tg2[pos] = (tg2[pos] + b) % P;
    ll &r = t[pos].v;int len = t[pos].r - t[pos].l + 1;
    r += a * (pw1[len] - 1 + P) % P * Q1 % P;
    r -= b * (pw2[len] - 1 + P) % P * Q2 % P;
    r = (r % P + P) % P;
}
inline void pushdown(int pos)
{
    int mid = (t[pos].l + t[pos].r) >> 1;
    add(lc(pos),tg1[pos],tg2[pos]);
    add(rc(pos),tg1[pos] * pw1[mid - t[pos].l + 1] % P,
        tg2[pos] * pw2[mid - t[pos].l + 1] % P);
    tg1[pos] = tg2[pos] = 0;
}
void modify(int pos,int l,int r,int v)
{
    if (t[pos].l == l && t[pos].r == r)
    {
        add(pos,S5D5 * pw1[l - v + 1] % P,S5D5 * pw2[l - v + 1] % P);
        return;
    }
    pushdown(pos);
    int mid = (t[pos].l + t[pos].r) >> 1;
    if (r <= mid) modify(lc(pos),l,r,v);
    else if (l > mid) modify(rc(pos),l,r,v);
    else modify(lc(pos),l,mid,v),modify(rc(pos),mid + 1,r,v);
    pushup(pos);
}
ll query(int pos,int l,int r)
{
    if (t[pos].l == l && t[pos].r == r) return t[pos].v;
    int mid = (t[pos].l + t[pos].r) >> 1;
    pushdown(pos);
    if (r <= mid) return query(lc(pos),l,r);
    else if (l > mid) return query(rc(pos),l,r);
    else return (query(lc(pos),l,mid) + query(rc(pos),mid + 1,r)) % P;
}
int main ()
{
    ios::sync_with_stdio(false);
    cin >> n >> m;
    for (int i = 1;i <= n;i++) cin >> a[i];
    pw1[0] = pw2[0] = 1;
    for (int i = 1;i <= n;i++)
    {
        pw1[i] = pw1[i - 1] * Q1 % P;pw2[i] = pw2[i - 1] * Q2 % P;
    }
    build(1,1,n);
    int t1,t2,t3;
    for (int i = 1;i <= m;i++)
    {
        cin >> t1 >> t2 >> t3;
        if (t1 == 1) modify(1,t2,t3,t2);
        else cout << query(1,t2,t3) << endl;
    }
    return 0;
}