#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 500;
int n, m;

class SegTree{
	typedef ll SegT;
	private:
		vector<SegT> val;
		int n;

	public:
		SegTree(const vector<SegT> &in){
			n=1;
			while(n<in.size())n<<=1;
			val=vector<SegT>(2*n, 0ll);
			for(int i=n-1 + in.size()-1;i>=0;i--){
				if(n-1 <= i) val[i] = in[i - (n-1)];
				else val[i] = val[i*2+1] + val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		//i ????v?f?? a ??X?V????
		void update(int i,SegT a){
			i+=n-1;
			val[i]+=a;
			if(val[i] >= MOD) val[i] -= MOD;
			while(i>0){
				i=(i-1)/2;
				val[i]=val[i*2+1]+val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		//[a, b) ??l??????????
		SegT query(int a,int b,int k=0,int l=0,int r=-1){
			if(r==-1)r=n;
			if(r<=a||b<=l) return 0ll;
			if(a<=l&&r<=b){
				return val[k];
			}else{
				SegT ret = query(a,b,k*2+1,l,(l+r)/2)+query(a,b,k*2+2,(l+r)/2,r);

				return ret>=MOD ? ret-MOD : ret;
			}
		}
};

ll F[300005];
ll sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002){
		sumFib[i+1] = sumFib[i] + F[i];
		if(sumFib[i+1] >= MOD) sumFib[i+1] -= MOD;
	}
	scanf("%d%d", &n, &m);
	vector<ll> init(n+1);
	REP(i, n) scanf("%I64d", &init[i+1]);
	SegTree seg(init);

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<ll> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = seg.query(l, r);
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - F[r-l-1];
//				printf("fib[%d] += MOD - %d\n", r, F[r-l]);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
				if(fib[r+1] >= MOD) fib[r+1] -= MOD;
			}
		}
		p += BLOCK;
//		cout << fib << endl;
		REP(i, n+1){
			if(i+2 < n+2){
				fib[i+2] += fib[i+1] + fib[i];
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			seg.update(i, fib[i]);
		}
//		cout << fib << endl;
//		REP(i, n+1) printf("%d ", seg.query(i+1, i+2));
//		puts("");
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 700;
int n, m;

class SegTree{
	typedef ll SegT;
	private:
		vector<SegT> val;
		int n;

	public:
		SegTree(const vector<SegT> &in){
			n=1;
			while(n<in.size())n<<=1;
			val=vector<SegT>(2*n, 0ll);
			for(int i=n-1 + in.size()-1;i>=0;i--){
				if(n-1 <= i) val[i] = in[i - (n-1)];
				else val[i] = val[i*2+1] + val[i*2+2];
				val[i] %= MOD;
			}
		}
		//i �Ԗڂ̗v�f�� a �ɍX�V����
		void update(int i,SegT a){
			i+=n-1;
			(val[i]+=a)%=MOD;
			while(i>0){
				i=(i-1)/2;
				val[i]=(val[i*2+1]+val[i*2+2])%MOD;
			}
		}
		//[a, b) �̒l������Ă���
		SegT query(int a,int b,int k=0,int l=0,int r=-1){
			if(r==-1)r=n;
			if(r<=a||b<=l) return 0ll;
			if(a<=l&&r<=b){
				return val[k];
			}else{
				SegT ret = query(a,b,k*2+1,l,(l+r)/2)+query(a,b,k*2+2,(l+r)/2,r);

				return ret%MOD;
			}
		}
};

ll F[300005];
ll sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002){
		sumFib[i+1] = sumFib[i] + F[i];
		if(sumFib[i+1] >= MOD) sumFib[i+1] -= MOD;
	}
	scanf("%d%d", &n, &m);
	vector<ll> init(n+1);
	REP(i, n) scanf("%I64d", &init[i+1]);
	SegTree seg(init);

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<ll> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = seg.query(l, r);
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - F[r-l-1];
//				printf("fib[%d] += MOD - %d\n", r, F[r-l]);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
				if(fib[r+1] >= MOD) fib[r+1] -= MOD;
			}
		}
		p += BLOCK;
//		cout << fib << endl;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += fib[i+1] + fib[i];
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			seg.update(i, fib[i]);
		}
//		cout << fib << endl;
//		REP(i, n+1) printf("%d ", seg.query(i+1, i+2));
//		puts("");
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 700;
int n, m;

class SegTree{
	typedef ll SegT;
	private:
		vector<SegT> val;
		int n;

	public:
		SegTree(const vector<SegT> &in){
			n=1;
			while(n<in.size())n<<=1;
			val=vector<SegT>(2*n, 0ll);
			for(int i=n-1 + in.size()-1;i>=0;i--){
				if(n-1 <= i) val[i] = in[i - (n-1)];
				else val[i] = val[i*2+1] + val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		//i �Ԗڂ̗v�f�� a �ɍX�V����
		void update(int i,SegT a){
			i+=n-1;
			val[i]+=a;
			if(val[i] >= MOD) val[i] -= MOD;
			while(i>0){
				i=(i-1)/2;
				val[i]=val[i*2+1]+val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		//[a, b) �̒l������Ă���
		SegT query(int a,int b,int k=0,int l=0,int r=-1){
			if(r==-1)r=n;
			if(r<=a||b<=l) return 0ll;
			if(a<=l&&r<=b){
				return val[k];
			}else{
				SegT ret = query(a,b,k*2+1,l,(l+r)/2)+query(a,b,k*2+2,(l+r)/2,r);

				return ret>=MOD ? ret-MOD : ret;
			}
		}
};

ll F[300005];
ll sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002){
		sumFib[i+1] = sumFib[i] + F[i];
		if(sumFib[i+1] >= MOD) sumFib[i+1] -= MOD;
	}
	scanf("%d%d", &n, &m);
	vector<ll> init(n+1);
	REP(i, n) scanf("%I64d", &init[i+1]);
	SegTree seg(init);

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<ll> fib(n+2);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = seg.query(l, r);
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - F[r-l-1];
//				printf("fib[%d] += MOD - %d\n", r, F[r-l]);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
				if(fib[r+1] >= MOD) fib[r+1] -= MOD;
			}
		}
		p += BLOCK;
//		cout << fib << endl;
		REP(i, n+1){
			if(i+2 < n+2){
				fib[i+2] += fib[i+1] + fib[i];
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			seg.update(i, fib[i]);
		}
//		cout << fib << endl;
//		REP(i, n+1) printf("%d ", seg.query(i+1, i+2));
//		puts("");
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 500;
int n, m;

int F[300005];
int sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002) sumFib[i+1] = (sumFib[i] + F[i]) % MOD;

	scanf("%d%d", &n, &m);
	vector<int> init(n+1), sum(n+2);
	REP(i, n) scanf("%I64d", &init[i+1]);
	REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<int> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = sum[r] - sum[l];
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
				if(fib[l] >= MOD) fib[l] %= MOD;
				if(fib[r] >= MOD) fib[r] %= MOD;
				if(fib[r+1] >= MOD) fib[r+1] %= MOD;
			}
		}
		p += BLOCK;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += (fib[i+1] + fib[i])%MOD;
				while(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			(init[i] += fib[i]) %= MOD;
			sum[i+1] = (sum[i] + init[i]) % MOD;
		}
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 600;
int n, m;

int F[300005];
int sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002) sumFib[i+1] = (sumFib[i] + F[i]) % MOD;

	scanf("%d%d", &n, &m);
	vector<ll> init(n+1), sum(n+2);
	REP(i, n) scanf("%I64d", &init[i+1]);
	REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<ll> fib(n+3);
		vi upd;
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = sum[r] - sum[l];
				REP(j, upd.size();){
					if(Q[p+upd[j]].S == 1){
						int ll = max(l, Q[p+upd[j]].F.F);
						int rr = min(r, Q[p+upd[j]].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+upd[j]].F.F] - sumFib[ll - Q[p+upd[j]].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
//				printf("fib[%d] += MOD - %d\n", r, F[r-l]);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
				if(fib[r+1] >= MOD) fib[r+1] -= MOD;
				upd.push_back(i);
			}
		}
		p += BLOCK;
//		cout << fib << endl;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += fib[i+1] + fib[i];
				while(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			(init[i] += fib[i]) %= MOD;
		}
		REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;
//		cout << fib << endl;
//		REP(i, n+1) printf("%d ", seg.query(i+1, i+2));
//		puts("");
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 1050;
int n, m;

int F[300005];
int sumFib[300005];
int qt[300005];
int ql[300005];
int qr[300005];
int init[300005];
int sum[300005];
int fib[300005];

main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002) sumFib[i+1] = (sumFib[i] + F[i]) % MOD;

	scanf("%d%d", &n, &m);
	REP(i, n) scanf("%I64d", &init[i+1]);
	REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;

	REP(i, m){
		scanf("%d%d%d", &qt[i], &ql[i], &qr[i]);
	}
	int p = 0;
	while(p<m){
		REP(i, BLOCK){
			if(p+i >= m) break;
			int l = ql[p+i];
			int r = qr[p+i];
			if(qt[p+i] == 2){
				ll res = sum[r] - sum[l];
				REP(j, i){
					if(qt[p+j] == 1){
						int ll = max(l, ql[p+j]);
						int rr = min(r, qr[p+j]);
						if(ll < rr) res += sumFib[rr - ql[p+j]] - sumFib[ll - ql[p+j]];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
				if(fib[l] >= MOD) fib[l] %= MOD;
				if(fib[r] >= MOD) fib[r] %= MOD;
				if(fib[r+1] >= MOD) fib[r+1] %= MOD;
			}
		}
		p += BLOCK;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+3){
			if(i+2 < n+3){
				fib[i+2] += (fib[i+1] + fib[i])%MOD;
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			(init[i] += fib[i]) %= MOD;
			sum[i+1] = (sum[i] + init[i]) % MOD;
			fib[i] = 0;
		}
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 500;
int n, m;

int F[300005];
int sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002) sumFib[i+1] = (sumFib[i] + F[i]) % MOD;

	scanf("%d%d", &n, &m);
	vector<int> init(n+1), sum(n+2);
	REP(i, n) scanf("%I64d", &init[i+1]);
	REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<int> fib(n+3);
		vi upd;
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = sum[r] - sum[l];
				REP(j, upd.size()){
					if(Q[p+upd[j]].S == 1){
						int ll = max(l, Q[p+upd[j]].F.F);
						int rr = min(r, Q[p+upd[j]].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+upd[j]].F.F] - sumFib[ll - Q[p+upd[j]].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
				if(fib[r+1] >= MOD) fib[r+1] -= MOD;
				upd.push_back(i);
			}
		}
		p += BLOCK;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += (fib[i+1] + fib[i])%MOD;
				while(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			(init[i] += fib[i]) %= MOD;
			sum[i+1] = (sum[i] + init[i]) % MOD;
		}
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 700;
int n, m;

class SegTree{
	typedef int SegT;
	private:
		vector<SegT> val;
		int n;

	public:
		SegTree(const vector<SegT> &in){
			n=1;
			while(n<in.size())n<<=1;
			val=vector<SegT>(2*n, 0ll);
			for(int i=n-1 + in.size()-1;i>=0;i--){
				if(n-1 <= i) val[i] = in[i - (n-1)];
				else val[i] = val[i*2+1] + val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		//i �Ԗڂ̗v�f�� a �ɍX�V����
		void update(int i,SegT a){
			i+=n-1;
			val[i]+=a;
			if(val[i] >= MOD) val[i] -= MOD;
			while(i>0){
				i=(i-1)/2;
				val[i]=val[i*2+1]+val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		//[a, b) �̒l������Ă���
		SegT query(int a,int b,int k=0,int l=0,int r=-1){
			if(r==-1)r=n;
			if(r<=a||b<=l) return 0ll;
			if(a<=l&&r<=b){
				return val[k];
			}else{
				SegT ret = query(a,b,k*2+1,l,(l+r)/2)+query(a,b,k*2+2,(l+r)/2,r);

				return ret>=MOD ? ret-MOD : ret;
			}
		}
};

int F[300005];
int sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300000){
		sumFib[i+1] = sumFib[i] + F[i];
		if(sumFib[i+1] >= MOD) sumFib[i+1] -= MOD;
	}
	scanf("%d%d", &n, &m);
	vi init(n+1);
	REP(i, n) scanf("%d", &init[i+1]);
	SegTree seg(init);

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vi fib(n+2);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = seg.query(l, r);
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", (res % MOD + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
//				printf("fib[%d] += MOD - %d\n", r, F[r-l]);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
			}
		}
		p += BLOCK;
//		cout << fib << endl;
		REP(i, n+1){
			if(i+2 < n+2){
				fib[i+2] += fib[i+1] + fib[i];
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			seg.update(i, fib[i]);
		}
//		cout << fib << endl;
//		REP(i, n+1) printf("%d ", seg.query(i+1, i+2));
//		puts("");
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 500;
int n, m;

class SegTree{
	typedef ll SegT;
	private:
		vector<SegT> val;
		int n;

	public:
		SegTree(const vector<SegT> &in){
			n=1;
			while(n<in.size())n<<=1;
			val=vector<SegT>(2*n, 0ll);
			for(int i=n-1 + in.size()-1;i>=0;i--){
				if(n-1 <= i) val[i] = in[i - (n-1)];
				else val[i] = val[i*2+1] + val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		//i ????v?f?? a ??X?V????
		void update(int i,SegT a){
			i+=n-1;
			val[i]+=a;
			if(val[i] >= MOD) val[i] -= MOD;
			while(i>0){
				i=(i-1)/2;
				val[i]=val[i*2+1]+val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		//[a, b) ??l??????????
		SegT query(int a,int b,int k=0,int l=0,int r=-1){
			if(r==-1)r=n;
			if(r<=a||b<=l) return 0ll;
			if(a<=l&&r<=b){
				return val[k];
			}else{
				SegT ret = query(a,b,k*2+1,l,(l+r)/2)+query(a,b,k*2+2,(l+r)/2,r);

				return ret>=MOD ? ret-MOD : ret;
			}
		}
};

ll F[300005];
ll sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002){
		sumFib[i+1] = sumFib[i] + F[i];
		if(sumFib[i+1] >= MOD) sumFib[i+1] -= MOD;
	}
	scanf("%d%d", &n, &m);
	vector<ll> init(n+1);
	REP(i, n) scanf("%I64d", &init[i+1]);
	SegTree seg(init);

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<ll> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = seg.query(l, r);
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - F[r-l-1];
//				printf("fib[%d] += MOD - %d\n", r, F[r-l]);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
				if(fib[r+1] >= MOD) fib[r+1] -= MOD;
			}
		}
		p += BLOCK;
//		cout << fib << endl;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+2){
				fib[i+2] += fib[i+1] + fib[i];
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			seg.update(i, fib[i]);
		}
//		cout << fib << endl;
//		REP(i, n+1) printf("%d ", seg.query(i+1, i+2));
//		puts("");
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 500;
int n, m;

int F[300005];
int sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002) sumFib[i+1] = (sumFib[i] + F[i]) % MOD;

	scanf("%d%d", &n, &m);
	vector<int> init(n+1), sum(n+2);
	REP(i, n) scanf("%I64d", &init[i+1]);
	REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<int> fib(n+3);
		vi upd;
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = sum[r] - sum[l];
				REP(j, upd.size()){
					if(Q[p+upd[j]].S == 1){
						int ll = max(l, Q[p+upd[j]].F.F);
						int rr = min(r, Q[p+upd[j]].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+upd[j]].F.F] - sumFib[ll - Q[p+upd[j]].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
				if(fib[r+1] >= MOD) fib[r+1] -= MOD;
				upd.push_back(i);
			}
		}
		p += BLOCK;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += fib[i+1] + fib[i];
				while(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			(init[i] += fib[i]) %= MOD;
			sum[i+1] = (sum[i] + init[i]) % MOD;
		}
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 1000;
int n, m;

class SegTree{
	typedef ll SegT;
	private:
		vector<SegT> val;
		int n;

	public:
		SegTree(const vector<SegT> &in){
			n=1;
			while(n<in.size())n<<=1;
			val=vector<SegT>(2*n, 0ll);
			for(int i=n-1 + in.size()-1;i>=0;i--){
				if(n-1 <= i) val[i] = in[i - (n-1)];
				else val[i] = val[i*2+1] + val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		void update(int i,SegT a){
			i+=n-1;
			val[i]+=a;
			if(val[i] >= MOD) val[i] -= MOD;
			while(i>0){
				i=(i-1)/2;
				val[i]=val[i*2+1]+val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		SegT query(int a,int b,int k=0,int l=0,int r=-1){
			if(r==-1)r=n;
			if(r<=a||b<=l) return 0ll;
			if(a<=l&&r<=b){
				return val[k];
			}else{
				SegT ret = query(a,b,k*2+1,l,(l+r)/2)+query(a,b,k*2+2,(l+r)/2,r);

				return ret>=MOD ? ret-MOD : ret;
			}
		}
};

ll F[300005];
ll sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002){
		sumFib[i+1] = sumFib[i] + F[i];
		if(sumFib[i+1] >= MOD) sumFib[i+1] -= MOD;
	}
	scanf("%d%d", &n, &m);
	vector<ll> init(n+1);
	REP(i, n) scanf("%I64d", &init[i+1]);
	SegTree seg(init);

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<ll> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = seg.query(l, r);
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
//				printf("fib[%d] += MOD - %d\n", r, F[r-l]);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
				if(fib[r+1] >= MOD) fib[r+1] -= MOD;
			}
		}
		p += BLOCK;
//		cout << fib << endl;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += fib[i+1] + fib[i];
				fib[i+2] %= MOD;
			}
			seg.update(i, fib[i]);
		}
//		if(n == 1865) cout << "BEND" << endl;
//		cout << fib << endl;
//		REP(i, n+1) printf("%d ", seg.query(i+1, i+2));
//		puts("");
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 1000;
int n, m;

class SegTree{
	typedef ll SegT;
	private:
		vector<SegT> val;
		int n;

	public:
		SegTree(const vector<SegT> &in){
			n=1;
			while(n<in.size())n<<=1;
			val=vector<SegT>(2*n, 0ll);
			for(int i=n-1 + in.size()-1;i>=0;i--){
				if(n-1 <= i) val[i] = in[i - (n-1)];
				else val[i] = val[i*2+1] + val[i*2+2];
				val[i] %= MOD;
			}
		}
		//i �Ԗڂ̗v�f�� a �ɍX�V����
		void update(int i,SegT a){
			i+=n-1;
			(val[i]+=a)%=MOD;
			while(i>0){
				i=(i-1)/2;
				val[i]=(val[i*2+1]+val[i*2+2])%MOD;
			}
		}
		//[a, b) �̒l������Ă���
		SegT query(int a,int b,int k=0,int l=0,int r=-1){
			if(r==-1)r=n;
			if(r<=a||b<=l) return 0ll;
			if(a<=l&&r<=b){
				return val[k];
			}else{
				SegT ret = query(a,b,k*2+1,l,(l+r)/2)+query(a,b,k*2+2,(l+r)/2,r);

				return ret%MOD;
			}
		}
};

ll F[300005];
ll sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	sumFib[0] = 0;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002){
		sumFib[i+1] = (sumFib[i] + F[i]) % MOD;
	}
	scanf("%d%d", &n, &m);
	vector<ll> init(n+1);
	REP(i, n) scanf("%I64d", &init[i+1]);
	SegTree seg(init);

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<ll> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = seg.query(l, r);
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				if(r-l-1 >= 0) fib[r+1] += MOD - F[r-l-1];
//				printf("fib[%d] += MOD - %d\n", r, F[r-l]);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
				if(fib[r+1] >= MOD) fib[r+1] -= MOD;
			}
		}
		p += BLOCK;
//		cout << fib << endl;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += (fib[i+1] + fib[i])%MOD;
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			seg.update(i, fib[i]);
		}
//		cout << fib << endl;
//		REP(i, n+1) printf("%d ", seg.query(i+1, i+2));
//		puts("");
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 1000;
int n, m;

class SegTree{
	typedef ll SegT;
	private:
		vector<SegT> val;
		int n;

	public:
		SegTree(const vector<SegT> &in){
			n=1;
			while(n<in.size())n<<=1;
			val=vector<SegT>(2*n, 0ll);
			for(int i=n-1 + in.size()-1;i>=0;i--){
				if(n-1 <= i) val[i] = in[i - (n-1)];
				else val[i] = val[i*2+1] + val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		void update(int i,SegT a){
			i+=n-1;
			val[i]+=a;
			if(val[i] >= MOD) val[i] -= MOD;
			while(i>0){
				i=(i-1)/2;
				val[i]=val[i*2+1]+val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		SegT query(int a,int b,int k=0,int l=0,int r=-1){
			if(r==-1)r=n;
			if(r<=a||b<=l) return 0ll;
			if(a<=l&&r<=b){
				return val[k];
			}else{
				SegT ret = query(a,b,k*2+1,l,(l+r)/2)+query(a,b,k*2+2,(l+r)/2,r);

				return ret>=MOD ? ret-MOD : ret;
			}
		}
};

ll F[300005];
ll sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002){
		sumFib[i+1] = sumFib[i] + F[i];
		if(sumFib[i+1] >= MOD) sumFib[i+1] -= MOD;
	}
	scanf("%d%d", &n, &m);
	vector<ll> init(n+1);
	REP(i, n) scanf("%I64d", &init[i+1]);
	SegTree seg(init);

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<ll> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = seg.query(l, r);
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
//				printf("fib[%d] += MOD - %d\n", r, F[r-l]);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
				if(fib[r+1] >= MOD) fib[r+1] -= MOD;
			}
		}
		p += BLOCK;
//		cout << fib << endl;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+2){
				fib[i+2] += fib[i+1] + fib[i];
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			seg.update(i, fib[i]);
		}
		cout << "BEND" << endl;
//		cout << fib << endl;
//		REP(i, n+1) printf("%d ", seg.query(i+1, i+2));
//		puts("");
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 500;
int n, m;

ll F[300005];
ll sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002){
		sumFib[i+1] = sumFib[i] + F[i];
		if(sumFib[i+1] >= MOD) sumFib[i+1] -= MOD;
	}
	scanf("%d%d", &n, &m);
	vector<ll> init(n+1), sum(n+2);
	REP(i, n) scanf("%I64d", &init[i+1]);
	REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<ll> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = sum[r] - sum[l];
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
//				printf("fib[%d] += MOD - %d\n", r, F[r-l]);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
				if(fib[r+1] >= MOD) fib[r+1] -= MOD;
			}
		}
		p += BLOCK;
//		cout << fib << endl;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += fib[i+1] + fib[i];
				while(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			(init[i] += fib[i]) %= MOD;
		}
		REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;
//		cout << fib << endl;
//		REP(i, n+1) printf("%d ", seg.query(i+1, i+2));
//		puts("");
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 1050;
int n, m;

int F[300005];
int sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002) sumFib[i+1] = (sumFib[i] + F[i]) % MOD;

	scanf("%d%d", &n, &m);
	vector<int> init(n+1), sum(n+2);
	REP(i, n) scanf("%I64d", &init[i+1]);
	REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<int> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = sum[r] - sum[l];
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
				if(fib[l] >= MOD) fib[l] %= MOD;
				if(fib[r] >= MOD) fib[r] %= MOD;
				if(fib[r+1] >= MOD) fib[r+1] %= MOD;
			}
		}
		p += BLOCK;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += (fib[i+1] + fib[i])%MOD;
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			(init[i] += fib[i]) %= MOD;
			sum[i+1] = (sum[i] + init[i]) % MOD;
		}
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 900;
int n, m;

int F[300005];
int sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002) sumFib[i+1] = (sumFib[i] + F[i]) % MOD;

	scanf("%d%d", &n, &m);
	vector<int> init(n+1), sum(n+2);
	REP(i, n) scanf("%I64d", &init[i+1]);
	REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<int> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = sum[r] - sum[l];
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
				if(fib[l] >= MOD) fib[l] %= MOD;
				if(fib[r] >= MOD) fib[r] %= MOD;
				if(fib[r+1] >= MOD) fib[r+1] %= MOD;
			}
		}
		p += BLOCK;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += (fib[i+1] + fib[i])%MOD;
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			(init[i] += fib[i]) %= MOD;
			sum[i+1] = (sum[i] + init[i]) % MOD;
		}
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 700;
int n, m;

class SegTree{
	typedef ll SegT;
	private:
		vector<SegT> val;
		int n;

	public:
		SegTree(const vector<SegT> &in){
			n=1;
			while(n<in.size())n<<=1;
			val=vector<SegT>(2*n, 0ll);
			for(int i=n-1 + in.size()-1;i>=0;i--){
				if(n-1 <= i) val[i] = in[i - (n-1)];
				else val[i] = val[i*2+1] + val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		//i ????v?f?? a ??X?V????
		void update(int i,SegT a){
			i+=n-1;
			val[i]+=a;
			if(val[i] >= MOD) val[i] -= MOD;
			while(i>0){
				i=(i-1)/2;
				val[i]=val[i*2+1]+val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		//[a, b) ??l??????????
		SegT query(int a,int b,int k=0,int l=0,int r=-1){
			if(r==-1)r=n;
			if(r<=a||b<=l) return 0ll;
			if(a<=l&&r<=b){
				return val[k];
			}else{
				SegT ret = query(a,b,k*2+1,l,(l+r)/2)+query(a,b,k*2+2,(l+r)/2,r);

				return ret>=MOD ? ret-MOD : ret;
			}
		}
};

ll F[300005];
ll sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002){
		sumFib[i+1] = sumFib[i] + F[i];
		if(sumFib[i+1] >= MOD) sumFib[i+1] -= MOD;
	}
	scanf("%d%d", &n, &m);
	vector<ll> init(n+1);
	REP(i, n) scanf("%I64d", &init[i+1]);
	SegTree seg(init);

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<ll> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = seg.query(l, r);
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - F[r-l-1];
//				printf("fib[%d] += MOD - %d\n", r, F[r-l]);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
				if(fib[r+1] >= MOD) fib[r+1] -= MOD;
			}
		}
		p += BLOCK;
//		cout << fib << endl;
		REP(i, n+1){
			if(i+2 < n+2){
				fib[i+2] += fib[i+1] + fib[i];
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			seg.update(i, fib[i]);
		}
//		cout << fib << endl;
//		REP(i, n+1) printf("%d ", seg.query(i+1, i+2));
//		puts("");
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 300;
int n, m;

class SegTree{
	typedef ll SegT;
	private:
		vector<SegT> val;
		int n;

	public:
		SegTree(const vector<SegT> &in){
			n=1;
			while(n<in.size())n<<=1;
			val=vector<SegT>(2*n, 0ll);
			for(int i=n-1 + in.size()-1;i>=0;i--){
				if(n-1 <= i) val[i] = in[i - (n-1)];
				else val[i] = val[i*2+1] + val[i*2+2];
				val[i] %= MOD;
			}
		}
		//i �Ԗڂ̗v�f�� a �ɍX�V����
		void update(int i,SegT a){
			i+=n-1;
			(val[i]+=a)%=MOD;
			while(i>0){
				i=(i-1)/2;
				val[i]=(val[i*2+1]+val[i*2+2])%MOD;
			}
		}
		//[a, b) �̒l������Ă���
		SegT query(int a,int b,int k=0,int l=0,int r=-1){
			if(r==-1)r=n;
			if(r<=a||b<=l) return 0ll;
			if(a<=l&&r<=b){
				return val[k];
			}else{
				SegT ret = query(a,b,k*2+1,l,(l+r)/2)+query(a,b,k*2+2,(l+r)/2,r);

				return ret%MOD;
			}
		}
};

ll F[300005];
ll sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	sumFib[0] = 0;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002){
		sumFib[i+1] = (sumFib[i] + F[i]) % MOD;
	}
	scanf("%d%d", &n, &m);
	vector<ll> init(n+1);
	REP(i, n) scanf("%I64d", &init[i+1]);
	SegTree seg(init);

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<ll> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = seg.query(l, r);
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				if(r-l-1 >= 0) fib[r+1] += MOD - F[r-l-1];
//				printf("fib[%d] += MOD - %d\n", r, F[r-l]);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
				if(fib[r+1] >= MOD) fib[r+1] -= MOD;
			}
		}
		p += BLOCK;
//		cout << fib << endl;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += (fib[i+1] + fib[i])%MOD;
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			seg.update(i, fib[i]);
		}
//		cout << fib << endl;
//		REP(i, n+1) printf("%d ", seg.query(i+1, i+2));
//		puts("");
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 1100;
int n, m;

int F[300005];
int sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002) sumFib[i+1] = (sumFib[i] + F[i]) % MOD;

	scanf("%d%d", &n, &m);
	vector<int> init(n+1), sum(n+2);
	REP(i, n) scanf("%I64d", &init[i+1]);
	REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<int> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = sum[r] - sum[l];
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
				if(fib[l] >= MOD) fib[l] %= MOD;
				if(fib[r] >= MOD) fib[r] %= MOD;
				if(fib[r+1] >= MOD) fib[r+1] %= MOD;
			}
		}
		p += BLOCK;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += (fib[i+1] + fib[i])%MOD;
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			(init[i] += fib[i]) %= MOD;
			sum[i+1] = (sum[i] + init[i]) % MOD;
		}
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 800;
int n, m;

int F[300005];
int sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002) sumFib[i+1] = (sumFib[i] + F[i]) % MOD;

	scanf("%d%d", &n, &m);
	vector<int> init(n+1), sum(n+2);
	REP(i, n) scanf("%I64d", &init[i+1]);
	REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<int> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = sum[r] - sum[l];
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
				if(fib[l] >= MOD) fib[l] %= MOD;
				if(fib[r] >= MOD) fib[r] %= MOD;
				if(fib[r+1] >= MOD) fib[r+1] %= MOD;
			}
		}
		p += BLOCK;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += (fib[i+1] + fib[i])%MOD;
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			(init[i] += fib[i]) %= MOD;
			sum[i+1] = (sum[i] + init[i]) % MOD;
		}
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 600;
int n, m;

int F[300005];
int sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002) sumFib[i+1] = (sumFib[i] + F[i]) % MOD;

	scanf("%d%d", &n, &m);
	vector<ll> init(n+1), sum(n+2);
	REP(i, n) scanf("%I64d", &init[i+1]);
	REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<ll> fib(n+3);
		vi upd;
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = sum[r] - sum[l];
				REP(j, upd.size()){
					if(Q[p+upd[j]].S == 1){
						int ll = max(l, Q[p+upd[j]].F.F);
						int rr = min(r, Q[p+upd[j]].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+upd[j]].F.F] - sumFib[ll - Q[p+upd[j]].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
//				printf("fib[%d] += MOD - %d\n", r, F[r-l]);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
				if(fib[r+1] >= MOD) fib[r+1] -= MOD;
				upd.push_back(i);
			}
		}
		p += BLOCK;
//		cout << fib << endl;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += fib[i+1] + fib[i];
				while(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			(init[i] += fib[i]) %= MOD;
		}
		REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;
//		cout << fib << endl;
//		REP(i, n+1) printf("%d ", seg.query(i+1, i+2));
//		puts("");
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 1000;
int n, m;

class SegTree{
	typedef ll SegT;
	private:
		vector<SegT> val;
		int n;

	public:
		SegTree(const vector<SegT> &in){
			n=1;
			while(n<in.size())n<<=1;
			val=vector<SegT>(2*n, 0ll);
			for(int i=n-1 + in.size()-1;i>=0;i--){
				if(n-1 <= i) val[i] = in[i - (n-1)];
				else val[i] = val[i*2+1] + val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		void update(int i,SegT a){
			i+=n-1;
			val[i]+=a;
			if(val[i] >= MOD) val[i] -= MOD;
			while(i>0){
				i=(i-1)/2;
				val[i]=val[i*2+1]+val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		SegT query(int a,int b,int k=0,int l=0,int r=-1){
			if(r==-1)r=n;
			if(r<=a||b<=l) return 0ll;
			if(a<=l&&r<=b){
				return val[k];
			}else{
				SegT ret = query(a,b,k*2+1,l,(l+r)/2)+query(a,b,k*2+2,(l+r)/2,r);

				return ret>=MOD ? ret-MOD : ret;
			}
		}
};

ll F[300005];
ll sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002){
		sumFib[i+1] = sumFib[i] + F[i];
		if(sumFib[i+1] >= MOD) sumFib[i+1] -= MOD;
	}
	scanf("%d%d", &n, &m);
	vector<ll> init(n+1);
	REP(i, n) scanf("%I64d", &init[i+1]);
	SegTree seg(init);

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<ll> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = seg.query(l, r);
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
//				printf("fib[%d] += MOD - %d\n", r, F[r-l]);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
				if(fib[r+1] >= MOD) fib[r+1] -= MOD;
			}
		}
		p += BLOCK;
//		cout << fib << endl;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+2){
				fib[i+2] += fib[i+1] + fib[i];
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			seg.update(i, fib[i]);
		}
//		cout << fib << endl;
//		REP(i, n+1) printf("%d ", seg.query(i+1, i+2));
//		puts("");
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 1000;
int n, m;

class SegTree{
	typedef ll SegT;
	private:
		vector<SegT> val;
		int n;

	public:
		SegTree(const vector<SegT> &in){
			n=1;
			while(n<in.size())n<<=1;
			val=vector<SegT>(2*n, 0ll);
			for(int i=n-1 + in.size()-1;i>=0;i--){
				if(n-1 <= i) val[i] = in[i - (n-1)];
				else val[i] = val[i*2+1] + val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		void update(int i,SegT a){
			i+=n-1;
			val[i]+=a;
			if(val[i] >= MOD) val[i] -= MOD;
			while(i>0){
				i=(i-1)/2;
				val[i]=val[i*2+1]+val[i*2+2];
				if(val[i] >= MOD) val[i] -= MOD;
			}
		}
		SegT query(int a,int b,int k=0,int l=0,int r=-1){
			if(r==-1)r=n;
			if(r<=a||b<=l) return 0ll;
			if(a<=l&&r<=b){
				return val[k];
			}else{
				SegT ret = query(a,b,k*2+1,l,(l+r)/2)+query(a,b,k*2+2,(l+r)/2,r);

				return ret>=MOD ? ret-MOD : ret;
			}
		}
};

ll F[300005];
ll sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002){
		sumFib[i+1] = sumFib[i] + F[i];
		if(sumFib[i+1] >= MOD) sumFib[i+1] -= MOD;
	}
	scanf("%d%d", &n, &m);
	vector<ll> init(n+1);
	REP(i, n) scanf("%I64d", &init[i+1]);
	SegTree seg(init);

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<ll> fib(n+3);
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = seg.query(l, r);
				REP(j, i){
					if(Q[p+j].S == 1){
						int ll = max(l, Q[p+j].F.F);
						int rr = min(r, Q[p+j].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+j].F.F] - sumFib[ll - Q[p+j].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - F[r-l-1];
//				printf("fib[%d] += MOD - %d\n", r, F[r-l]);
				if(fib[l] >= MOD) fib[l] -= MOD;
				if(fib[r] >= MOD) fib[r] -= MOD;
				if(fib[r+1] >= MOD) fib[r+1] -= MOD;
			}
		}
		p += BLOCK;
//		cout << fib << endl;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+2){
				fib[i+2] += fib[i+1] + fib[i];
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			seg.update(i, fib[i]);
		}
//		cout << fib << endl;
//		REP(i, n+1) printf("%d ", seg.query(i+1, i+2));
//		puts("");
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 1050;
int n, m;

int F[300005];
int sumFib[300005];
int qt[300005];
int ql[300005];
int qr[300005];
int init[300005];
int sum[300005];
int fib[300005];

main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002) sumFib[i+1] = (sumFib[i] + F[i]) % MOD;

	scanf("%d%d", &n, &m);
	REP(i, n) scanf("%I64d", &init[i+1]);
	REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;

	REP(i, m){
		scanf("%d%d%d", &qt[i], &ql[i], &qr[i]);
		qr[i] ++;
	}
	int p = 0;
	while(p<m){
		REP(i, BLOCK){
			if(p+i >= m) break;
			int l = ql[p+i];
			int r = qr[p+i];
			if(qt[p+i] == 2){
				ll res = sum[r] - sum[l];
				REP(j, i){
					if(qt[p+j] == 1){
						int ll = max(l, ql[p+j]);
						int rr = min(r, qr[p+j]);
						if(ll < rr) res += sumFib[rr - ql[p+j]] - sumFib[ll - ql[p+j]];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
				if(fib[l] >= MOD) fib[l] %= MOD;
				if(fib[r] >= MOD) fib[r] %= MOD;
				if(fib[r+1] >= MOD) fib[r+1] %= MOD;
			}
		}
		p += BLOCK;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+4){
			if(i+2 < n+3){
				fib[i+2] += (fib[i+1] + fib[i])%MOD;
				if(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			(init[i] += fib[i]) %= MOD;
			sum[i+1] = (sum[i] + init[i]) % MOD;
			fib[i] = 0;
		}
	}
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<pii, int> ppiii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define F first
#define S second
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000009;
const int BLOCK = 500;
int n, m;

int F[300005];
int sumFib[300005];
main(){
	F[0] = 1;
	F[1] = 1;
	REP(i, 300000) F[i+2] = (F[i+1] + F[i]) % MOD;
	REP(i, 300002) sumFib[i+1] = (sumFib[i] + F[i]) % MOD;

	scanf("%d%d", &n, &m);
	vector<int> init(n+1), sum(n+2);
	REP(i, n) scanf("%I64d", &init[i+1]);
	REP(i, n+1) sum[i+1] = (sum[i] + init[i]) % MOD;

	vector<ppiii> Q(m);
	REP(i, m){
		int t, l, r;
		scanf("%d%d%d", &t, &l, &r);
		Q[i] = ppiii(pii(l, r+1), t);
	}
	int p = 0;
	while(p<m){
		vector<int> fib(n+3);
		vi upd;
		REP(i, BLOCK){
			if(p+i >= m) break;
			ppiii &q = Q[p+i];
			int l = q.F.F;
			int r = q.F.S;
			if(q.S == 2){
				ll res = sum[r] - sum[l];
				REP(j, upd.size()){
					if(Q[p+upd[j]].S == 1){
						int ll = max(l, Q[p+upd[j]].F.F);
						int rr = min(r, Q[p+upd[j]].F.S);
						if(ll < rr) res += sumFib[rr - Q[p+upd[j]].F.F] - sumFib[ll - Q[p+upd[j]].F.F];
					}
				}
				printf("%I64d\n", ((res % MOD) + MOD) % MOD);
			}else{
				fib[l] += F[0];
				fib[r] += MOD - F[r-l];
				fib[r+1] += MOD - (r-l-1 >= 0 ? F[r-l-1] : 1);
				if(fib[l] >= MOD) fib[l] %= MOD;
				if(fib[r] >= MOD) fib[r] %= MOD;
				if(fib[r+1] >= MOD) fib[r+1] %= MOD;
				upd.push_back(i);
			}
		}
		p += BLOCK;
		fib[1] += fib[0];
		if(fib[1] >= MOD) fib[1] -= MOD;
		REP(i, n+1){
			if(i+2 < n+3){
				fib[i+2] += (fib[i+1] + fib[i])%MOD;
				while(fib[i+2] >= MOD) fib[i+2] -= MOD;
			}
			(init[i] += fib[i]) %= MOD;
			sum[i+1] = (sum[i] + init[i]) % MOD;
		}
	}
	return 0;
}


#include<cstdio>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
#include<string>
#include<string.h>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<map>
#include<set>
#include<iostream>
#include<sstream>
#include<cctype>
#define fi first
#define se second
#define rep(i,n) for(int i = 0; i < n; i++)
#define rrep(i,n) for(int i = 1; i <= n; i++)
#define drep(i,n) for(int i = n-1; i >= 0; i--)
#define gep(i,g,j) for(int i = g.head[j]; i != -1; i = g.e[i].next)
#define each(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++)
#define rng(a) a.begin(),a.end()
#define maxs(x,y) x = max(x,y)
#define mins(x,y) x = min(x,y)
#define pb push_back
#define sz(x) (int)(x).size()
#define pcnt __builtin_popcount
#define snuke srand((unsigned)clock()+(unsigned)time(NULL))
using namespace std;
typedef long long int ll;
typedef pair<int,int> P;
typedef vector<int> vi;

const int MX = 100005, INF = 1000010000;
const ll LINF = 1000000000000000000ll;
const double eps = 1e-10;
const int dx[] = {-1,0,1,0}, dy[] = {0,-1,0,1}; //<^>v
const int mod = 1000000009;

int f[MX], g[MX];

// Segment tree (RMQ type)
struct seg{
	vector<ll> d, e1, e2; int sz, sz2;
	seg(){}
	seg(int mx){
		sz = 1; while(sz < mx) sz <<= 1;
		sz2 = sz<<1; d.resize(sz2,0); e1.resize(sz2,0); e2.resize(sz2,0);
	}
	void fil(){ drep(i,sz) d[i] = d[i<<1]+d[i<<1|1];}
	void addr(int a, int b, int x, int y, int i=1, int l=0, int r=INF){
		if(r == INF) r = sz;
		if(a <= l && r <= b){
			e1[i] += x;
			e2[i] += y;
			return;
		}
		int c = l+r>>1;
		if(a < c) addr(a,b,x,y,i<<1,l,c);
		if(c < b) {
			int nx = 0, ny = 0, nc = c-l;
			(nx += x*f[nc+1])%=mod;
			(ny += x*f[nc])%=mod;
			(nx += y*f[nc])%=mod;
			if(c) (ny += y*f[nc-1])%=mod;
		  addr(a,b,nx,ny,i<<1|1,c,r);
		}
	}
	int qu(int a, int b, int i=1, int l=0, int r=INF){
		if(r == INF) r = sz;
		(d[i] += e1[i]*g[r-l])%=mod;
		(d[i] += e2[i]*g[r-l-1])%=mod;
		if (l+1 != r) {
			(e1[i<<1] += e1[i])%=mod;
			(e2[i<<1] += e2[i])%=mod;
			int c = (r-l)>>1;
			(e1[i<<1|1] += e1[i]*f[c+1])%=mod;
			(e2[i<<1|1] += e1[i]*f[c])%=mod;
			(e1[i<<1|1] += e2[i]*f[c])%=mod;
			if(c) (e2[i<<1|1] += e2[i]*f[c-1])%=mod;
		}
		e1[i] = e2[i] = 0;
		if(a <= l && r <= b) return d[i];
		int c = l+r>>1; int res = 0;
		if(a < c) (res += qu(a,b,i<<1,l,c)) %= mod;
		res %= mod;
		if(c < b) (res += qu(a,b,i<<1|1,c,r)) %= mod;
		res %= mod;
		return res;
	}
};
//

int main(){
	int n, m;
	scanf("%d%d",&n,&m);
	f[1] = f[2] = 1;
	rrep(i,n) f[i+2] = (f[i]+f[i+1])%mod;
	rep(i,n+3) g[i] = f[i];
	rrep(i,n+3) (g[i] += g[i-1]) %= mod;
	seg t(n+5);
	rep(i,n) scanf("%I64d",&t.d[t.sz+i]);
	t.fil();
	rep(j,m){
		int tp, l, r;
		scanf("%d%d%d",&tp,&l,&r);
		--l;
		if(tp == 1) {
			t.addr(l, r, 1, 0);
		} else {
			printf("%d\n",t.qu(l, r));
		}
	}

	return 0;
}


#include<cstdio>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
#include<string>
#include<string.h>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<map>
#include<set>
#include<iostream>
#include<sstream>
#include<cctype>
#define fi first
#define se second
#define rep(i,n) for(int i = 0; i < n; i++)
#define rrep(i,n) for(int i = 1; i <= n; i++)
#define drep(i,n) for(int i = n-1; i >= 0; i--)
#define gep(i,g,j) for(int i = g.head[j]; i != -1; i = g.e[i].next)
#define each(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++)
#define rng(a) a.begin(),a.end()
#define maxs(x,y) x = max(x,y)
#define mins(x,y) x = min(x,y)
#define pb push_back
#define sz(x) (int)(x).size()
#define pcnt __builtin_popcount
#define snuke srand((unsigned)clock()+(unsigned)time(NULL))
using namespace std;
typedef long long int ll;
typedef pair<int,int> P;
typedef vector<int> vi;

const int MX = 300005, INF = 1000010000;
const ll LINF = 1000000000000000000ll;
const double eps = 1e-10;
const int dx[] = {-1,0,1,0}, dy[] = {0,-1,0,1}; //<^>v
const int mod = 1000000009;

int f[MX*2], g[MX*2];

// Segment tree (RMQ type)
struct seg{
	vector<ll> d, e1, e2; int sz, sz2;
	seg(){}
	seg(int mx){
		sz = 1; while(sz < mx) sz <<= 1;
		sz2 = sz<<1; d.resize(sz2,0); e1.resize(sz2,0); e2.resize(sz2,0);
	}
	void fil(){ drep(i,sz) d[i] = d[i<<1]+d[i<<1|1];}
	void addr(int a, int b, int x, int y, int i=1, int l=0, int r=INF){
		if(r == INF) r = sz;
		if(a <= l && r <= b){
			e1[i] += x;
			e2[i] += y;
			return;
		}
		int nr = min(r,b);
		int nl = max(l,a);
		(d[i] += e1[i]*g[nr-nl])%=mod;
		(d[i] += e2[i]*g[nr-nl-1])%=mod;
		int c = l+r>>1;
		if(a < c) addr(a,b,x,y,i<<1,l,c);
		if(c < b) {
			int nx = 0, ny = 0, nc = max(0,c-max(a,l));
			(nx += x*f[nc+1])%=mod;
			(ny += x*f[nc])%=mod;
			(nx += y*f[nc])%=mod;
			if(c) (ny += y*f[nc-1])%=mod;
		  addr(a,b,nx,ny,i<<1|1,c,r);
		}
	}
	int qu(int a, int b, int i=1, int l=0, int r=INF){
		if(r == INF) r = sz;
		(d[i] += e1[i]*g[r-l])%=mod;
		(d[i] += e2[i]*g[r-l-1])%=mod;
		if (l+1 != r) {
			(e1[i<<1] += e1[i])%=mod;
			(e2[i<<1] += e2[i])%=mod;
			int c = (r-l)>>1;
			(e1[i<<1|1] += e1[i]*f[c+1])%=mod;
			(e2[i<<1|1] += e1[i]*f[c])%=mod;
			(e1[i<<1|1] += e2[i]*f[c])%=mod;
			if(c) (e2[i<<1|1] += e2[i]*f[c-1])%=mod;
		}
		e1[i] = e2[i] = 0;
		if(a <= l && r <= b) return d[i];
		int c = l+r>>1; int res = 0;
		if(a < c) (res += qu(a,b,i<<1,l,c)) %= mod;
		res %= mod;
		if(c < b) (res += qu(a,b,i<<1|1,c,r)) %= mod;
		res %= mod;
		return res;
	}
};
//

int main(){
	int n, m;
	scanf("%d%d",&n,&m);
	f[1] = f[2] = 1;
	rrep(i,n*2+5) f[i+2] = (f[i]+f[i+1])%mod;
	rep(i,n*2+5) g[i] = f[i];
	rrep(i,n*2+5) (g[i] += g[i-1]) %= mod;
	seg t(n+5);
	rep(i,n) scanf("%I64d",&t.d[t.sz+i]);
	t.fil();
	rep(j,m){
		int tp, l, r;
		scanf("%d%d%d",&tp,&l,&r);
		--l;
		if(tp == 1) {
			t.addr(l, r, 1, 0);
		} else {
			printf("%d\n",t.qu(l, r));
		}
	}

	return 0;
}