#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <ii> vii;
typedef vector <vii> vvii;
#define endl '\n'
#define PB push_back
#define MP make_pair
#define OO (1000000000)         // ToDo
#define EPS (1e-9)              // ToDo
#define MOD (1000000009)        // ToDo
#define all(v) ((v).begin()),((v).end())
#define DEBUG(x) cout<< #x <<" = "<<"\""<< (x) <<"\""<<endl
#define FASTIO ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
void read_file(bool outToFile = true){
#ifdef LOCAL_TEST
    freopen("in.in", "rt", stdin);
    if(outToFile)
    freopen("out.out", "wt", stdout);
#endif
}
//
#define nMax 300000+2+1
int n, nq;
//
inline void add(int &x, int v){
    x += v;
    if(x >= MOD) x -= MOD;
}
//

//
// fibo stuff begin
//
const int matMax = 2;
struct matrix{
    int n, m;
    int mat[matMax][matMax];

    matrix(){

    }

    matrix(int nn, int nm, int d=0){
        n = nn, m = nm;
        memset(mat, 0, sizeof mat);

        if(d)
        {
            for(int i=0; i<n; i++)
                mat[i][i] = d;
        }
    }

    matrix operator+ (const matrix &B) const{
        assert(n == B.n && m == B.m);

        matrix C = *this;
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
                add(C.mat[i][j], B.mat[i][j]);

        return C;
    }

    matrix operator* (const matrix &B) const{
        int p = B.m;
        assert(B.n == m);

        matrix C(n, p);
        for(int i=0; i<n; i++)
        {
            for(int k=0; k<m; k++)
            {
                if(mat[i][k] == 0) continue;
                for(int j=0; j<p; j++)
                    add(C.mat[i][j], 1LL * mat[i][k] * B.mat[k][j] %MOD);
            }
        }
        return C;
    }

    matrix operator* (const int &a) const{
        matrix ret(n, m);
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
                ret.mat[i][j] = mat[i][j] * a;
        return ret;
    }
};
//
matrix MAT[nMax];
matrix SMAT[nMax];
matrix T;
//
void build(){

    T = matrix(2, 2);
    T.mat[0][0] = 1;
    T.mat[0][1] = 1;
    T.mat[1][0] = 1;
    T.mat[1][1] = 0;

    MAT[0] = matrix(2, 2, 1);
    SMAT[0] = matrix(2, 2, 1);

    for(int i=1; i<nMax; i++)
    {
        MAT[i] = MAT[i-1] * T;
        SMAT[i] = SMAT[i-1] + MAT[i];
    }
}
int query_F(int f0, int f1, int n){

    matrix X0(2, 1);
    X0.mat[0][0] = f1;
    X0.mat[1][0] = f0;

    matrix cum = SMAT[n-1]* X0;
    int ret = cum.mat[1][0];
    return ret;
}
int get_F(int f0, int f1, int n){

    matrix X0(2, 1);
    X0.mat[0][0] = f1;
    X0.mat[1][0] = f0;

    matrix F = MAT[n] * X0;
    int ret = F.mat[1][0];
    return ret;
}
//
// fibo stuff end
//

//
// segment tree stuff begin
//
struct node{
    int val;
    int fst, scd;
};
//
#define stMax 1048576
node ST[stMax];
int GS, GE;
//
void init(){
    GS = 0, GE = n-1;
    for(int i=0; i<stMax; i++)
    {
        ST[i].val = 0;
        ST[i].fst = ST[i].scd = 0;
    }
}
void merge(int p){
    ST[p].val = ST[2*p].val;
    add(ST[p].val, ST[2*p+1].val);
}
void insert(int idx, int val, int s=GS, int e=GE, int p=1){

    if(s == e)
    {
        ST[p].val = val;
        return;
    }

    int m = (s+e)/2;
    if(idx <= m)
        insert(idx, val, s, m, 2*p);
    else
        insert(idx, val, m+1, e, 2*p+1);

    merge(p);
}
void update_node(int fst, int scd, int s, int e, int p){

    add(ST[p].fst, fst);

    add(ST[p].scd, scd);

    add(ST[p].val, query_F(fst, scd, e - s + 1));
}
void update_child(int s, int e, int p){
    int m = (s+e)/2;

    int f0 = ST[p].fst, f1 = ST[p].scd;
    update_node(f0, f1, s, m, 2*p);

    int k = m - s;
    int fkplus1 = get_F(f0, f1, k+1);
    int fkplus2 = get_F(f0, f1, k+2);
    update_node(fkplus1, fkplus2, m+1, e, 2*p+1);

    ST[p].fst = ST[p].scd = 0;
}
void update(int fr, int to, int fst, int scd, int s=GS, int e=GE, int p=1){

    if(fr <= s && e <= to)
    {
        update_node(fst, scd, s, e, p);
        return;
    }

    update_child(s, e, p);

    int m = (s+e)/2;
    if(to <= m)
        update(fr, to, fst, scd, s, m, 2*p);
    else if(fr >= m+1)
        update(fr, to, fst, scd, m+1, e, 2*p+1);
    else
    {
        update(fr, to, fst, scd, s, m, 2*p);

        // f0           f1              f2              ...             fl
        // max(fr, s)   ...             ...             ...             min(to, e)
        // m is included in [max(fr, s), min(to, e)] and opposite to fk

        int k = m - max(fr, s);
        int fkplus1 = get_F(fst, scd, k+1);
        int fkplus2 = get_F(fst, scd, k+2);

        update(fr, to, fkplus1, fkplus2, m+1, e, 2*p+1);
    }

    merge(p);
}
void update1(int fr, int to, int s=GS, int e=GE, int p=1){

    if(fr <= s && e <= to)
    {
        int f0 = get_F(0, 1, s - fr + 1);
        int f1 = get_F(0, 1, s - fr + 1 + 1);
        update_node(f0, f1, s, e, p);
        return;
    }

    update_child(s, e, p);

    int m = (s+e)/2;
    if(to <= m)
        update1(fr, to, s, m, 2*p);
    else if(fr >= m+1)
        update1(fr, to, m+1, e, 2*p+1);
    else
    {
        update1(fr, to, s, m, 2*p);
        update1(fr, to, m+1, e, 2*p+1);
    }

    merge(p);
}
int query(int fr, int to, int s=GS, int e=GE, int p=1){

    if(fr <= s && e <= to)
        return ST[p].val;

    update_child(s, e, p);

    int m = (s+e)/2;
    if(to <= m)
        return query(fr, to, s, m, 2*p);
    else if(fr >= m+1)
        return query(fr, to, m+1, e, 2*p+1);
    else
    {
        int ql = query(fr, to, s, m, 2*p);
        int qr = query(fr, to, m+1, e, 2*p+1);

        int ret = ql;
        add(ret, qr);
        return ret;
    }
}
//
// segment tree stuff end
//

int main()
{
    read_file();
    build();
    while(scanf("%d%d", &n, &nq)!=EOF)
    {
        init();
        for(int i=0; i<n; i++)
        {
            int x;
            scanf("%d", &x);
            insert(i, x);
        }

        while(nq--)
        {
            int cmd, fr, to;
            scanf("%d%d%d", &cmd, &fr, &to);
            fr--, to--;

            if(cmd == 1)
            {
                update(fr, to, 1, 1);
//                update1(fr, to);
                continue;
            }

            int ans;
            ans = query(fr, to);

            printf("%d\n", ans);
        }
        printf("\n");
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <ii> vii;
typedef vector <vii> vvii;
#define endl '\n'
#define PB push_back
#define MP make_pair
#define OO (1000000000)         // ToDo
#define EPS (1e-9)              // ToDo
#define MOD (1000000009)        // ToDo
#define all(v) ((v).begin()),((v).end())
#define DEBUG(x) cout<< #x <<" = "<<"\""<< (x) <<"\""<<endl
#define FASTIO ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
void read_file(bool outToFile = true){
#ifdef LOCAL_TEST
    freopen("in.in", "rt", stdin);
    if(outToFile)
    freopen("out.out", "wt", stdout);
#endif
}
//
#define nMax 300000+2+1
int n, nq;
//
void add(int &x, int v){
    x += v;
    if(x >= MOD) x -= MOD;
}
//

//
// fibo stuff begin
//
const int matMax = 2;
struct matrix{
    int n, m;
    int mat[matMax][matMax];
    matrix(int nn=0, int nm=0){
        n = nn, m = nm;
    }
};
matrix MAT[nMax];
matrix SMAT[nMax];
matrix T;
//
matrix zero(int n, int m){
    matrix A(n, m);
    memset(A.mat, 0, sizeof A.mat);
    return A;
}
matrix identity(int n){
    matrix A = zero(n, n);
    for(int i=0; i<n; i++)
        A.mat[i][i] = 1;
    return A;
}
matrix operator+ (matrix A, matrix B){
    int n, m;
    n = A.n, m = A.m;
    assert(n == B.n && m == B.m);

    matrix C = A;
    for(int i=0; i<n; i++)
        for(int j=0; j<m; j++)
            add(C.mat[i][j], B.mat[i][j]);

    return C;
}
matrix operator* (matrix A, matrix B){
    int n, m, p;
    n = A.n;
    m = A.m;
    p = B.m;
    assert(B.n == m);

    matrix C = zero(n, p);
    for(int i=0; i<n; i++)
    {
        for(int k=0; k<m; k++)
        {
            if(A.mat[i][k] == 0) continue;
            for(int j=0; j<p; j++)
                add(C.mat[i][j], 1LL * A.mat[i][k] * B.mat[k][j] %MOD);
        }
    }
    return C;
}
//
void build(){

    T = zero(2, 2);
    T.mat[0][0] = 1;
    T.mat[0][1] = 1;
    T.mat[1][0] = 1;
    T.mat[1][1] = 0;

    MAT[0] = identity(2);
    SMAT[0] = identity(2);

    for(int i=1; i<nMax; i++)
    {
        MAT[i] = MAT[i-1] * T;
        SMAT[i] = (SMAT[i-1] + MAT[i]);
    }
}
int query_F(int f0, int f1, int n){

    matrix X0 = zero(2, 1);
    X0.mat[0][0] = f1;
    X0.mat[1][0] = f0;

    matrix cum = SMAT[n-1]* X0;
    int ret = cum.mat[1][0];
    return ret;
}
int get_F(int f0, int f1, int n){

    matrix X0 = zero(2, 1);
    X0.mat[0][0] = f1;
    X0.mat[1][0] = f0;

    matrix F = (MAT[n]* X0);
    int ret = F.mat[1][0];
    return ret;
}
//
// fibo stuff end
//

//
// segment tree stuff begin
//
struct node{
    int val;
    int fst, scd;
};
//
#define stMax 1048576
node ST[stMax];
int GS, GE;
//
void init(){
    GS = 0, GE = n-1;
    for(int i=0; i<stMax; i++)
    {
        ST[i].val = 0;
        ST[i].fst = ST[i].scd = 0;
    }
}
void merge(int p){
    ST[p].val = ST[2*p].val;
    add(ST[p].val, ST[2*p+1].val);
}
void insert(int idx, int val, int s=GS, int e=GE, int p=1){

    if(s == e)
    {
        ST[p].val = val;
        return;
    }

    int m = (s+e)/2;
    if(idx <= m)
        insert(idx, val, s, m, 2*p);
    else
        insert(idx, val, m+1, e, 2*p+1);

    merge(p);
}
void update_node(int fst, int scd, int s, int e, int p){

    add(ST[p].fst, fst);

    add(ST[p].scd, scd);

    add(ST[p].val, query_F(fst, scd, e - s + 1));
}
void update_child(int s, int e, int p){
    int m = (s+e)/2;

    int f0 = ST[p].fst, f1 = ST[p].scd;
    update_node(f0, f1, s, m, 2*p);

    int k = m - s;
    int fkplus1 = get_F(f0, f1, k+1);
    int fkplus2 = get_F(f0, f1, k+2);
    update_node(fkplus1, fkplus2, m+1, e, 2*p+1);

    ST[p].fst = ST[p].scd = 0;
}
void update(int fr, int to, int fst, int scd, int s=GS, int e=GE, int p=1){

    if(fr <= s && e <= to)
    {
        update_node(fst, scd, s, e, p);
        return;
    }

    update_child(s, e, p);

    int m = (s+e)/2;
    if(to <= m)
        update(fr, to, fst, scd, s, m, 2*p);
    else if(fr >= m+1)
        update(fr, to, fst, scd, m+1, e, 2*p+1);
    else
    {
        update(fr, to, fst, scd, s, m, 2*p);

        // f0           f1              f2              ...             fl
        // max(fr, s)   ...             ...             ...             min(to, e)
        // m is included in [max(fr, s), min(to, e)] and opposite to fk

        int k = m - max(fr, s);
        int fkplus1 = get_F(fst, scd, k+1);
        int fkplus2 = get_F(fst, scd, k+2);

        update(fr, to, fkplus1, fkplus2, m+1, e, 2*p+1);
    }

    merge(p);
}
void update1(int fr, int to, int s=GS, int e=GE, int p=1){

    if(fr <= s && e <= to)
    {
        int f0 = get_F(0, 1, s - fr + 1);
        int f1 = get_F(0, 1, s - fr + 1 + 1);
        update_node(f0, f1, s, e, p);
        return;
    }

    update_child(s, e, p);

    int m = (s+e)/2;
    if(to <= m)
        update1(fr, to, s, m, 2*p);
    else if(fr >= m+1)
        update1(fr, to, m+1, e, 2*p+1);
    else
    {
        update1(fr, to, s, m, 2*p);
        update1(fr, to, m+1, e, 2*p+1);
    }

    merge(p);
}
int query(int fr, int to, int s=GS, int e=GE, int p=1){

    if(fr <= s && e <= to)
        return ST[p].val;

    update_child(s, e, p);

    int m = (s+e)/2;
    if(to <= m)
        return query(fr, to, s, m, 2*p);
    else if(fr >= m+1)
        return query(fr, to, m+1, e, 2*p+1);
    else
    {
        int ql = query(fr, to, s, m, 2*p);
        int qr = query(fr, to, m+1, e, 2*p+1);

        int ret = ql;
        add(ret, qr);
        return ret;
    }
}
//
// segment tree stuff end
//

int main()
{
    read_file();
    build();
    while(scanf("%d%d", &n, &nq)!=EOF)
    {
        init();
        for(int i=0; i<n; i++)
        {
            int x;
            scanf("%d", &x);
            insert(i, x);
        }

        while(nq--)
        {
            int cmd, fr, to;
            scanf("%d%d%d", &cmd, &fr, &to);
            fr--, to--;

            if(cmd == 1)
            {
                update(fr, to, 1, 1);
//                update1(fr, to);
                continue;
            }

            int ans;
            ans = query(fr, to);

            printf("%d\n", ans);
        }
        printf("\n");
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <ii> vii;
typedef vector <vii> vvii;
#define endl '\n'
#define PB push_back
#define MP make_pair
#define OO (1000000000)         // ToDo
#define EPS (1e-9)              // ToDo
#define MOD (1000000009)        // ToDo
#define all(v) ((v).begin()),((v).end())
#define DEBUG(x) cout<< #x <<" = "<<"\""<< (x) <<"\""<<endl
#define FASTIO ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
void read_file(bool outToFile = true){
#ifdef LOCAL_TEST
    freopen("in.in", "rt", stdin);
    if(outToFile)
    freopen("out.out", "wt", stdout);
#endif
}
//
#define nMax 300000+2+1
int n, nq;
//
void add(int &x, int v){
    x += v;
    if(x >= MOD) x -= MOD;
}
//

//
// fibo stuff begin
//
const int matMax = 2;
struct matrix{
    int n, m;
    int mat[matMax][matMax];
    matrix(int nn=0, int nm=0){
        n = nn, m = nm;
    }
};
matrix MAT[nMax];
matrix SMAT[nMax];
matrix T;
//
matrix zero(int n, int m){
    matrix A(n, m);
    memset(A.mat, 0, sizeof A.mat);
    return A;
}
matrix identity(int n){
    matrix A = zero(n, n);
    for(int i=0; i<n; i++)
        A.mat[i][i] = 1;
    return A;
}
matrix operator+ (matrix A, matrix B){
    int n, m;
    n = A.n, m = A.m;
    assert(n == B.n && m == B.m);

    matrix C = A;
    for(int i=0; i<n; i++)
        for(int j=0; j<m; j++)
            add(C.mat[i][j], B.mat[i][j]);

    return C;
}
matrix operator* (matrix A, matrix B){
    int n, m, p;
    n = A.n;
    m = A.m;
    p = B.m;
    assert(B.n == m);

    matrix C = zero(n, p);
    for(int i=0; i<n; i++)
    {
        for(int k=0; k<m; k++)
        {
            if(A.mat[i][k] == 0) continue;
            for(int j=0; j<p; j++)
                add(C.mat[i][j], 1LL * A.mat[i][k] * B.mat[k][j] %MOD);
        }
    }
    return C;
}
//
void build(){

    T = zero(2, 2);
    T.mat[0][0] = 1;
    T.mat[0][1] = 1;
    T.mat[1][0] = 1;
    T.mat[1][1] = 0;

    MAT[0] = identity(2);
    SMAT[0] = identity(2);

    for(int i=1; i<nMax; i++)
    {
        MAT[i] = MAT[i-1] * T;
        SMAT[i] = (SMAT[i-1] + MAT[i]);
    }
}
int query_F(int f0, int f1, int n){
    int a = SMAT[n-1].mat[1][0];
    int b = SMAT[n-1].mat[1][1];

    int ret = 1LL * a * f1 %MOD;
    add(ret, 1LL * b * f0 %MOD);
    return ret;
}
//int query_F(int f0, int f1, int n){
//
//    matrix X0 = zero(2, 1);
//    X0.mat[0][0] = f1;
//    X0.mat[1][0] = f0;
//
//    matrix cum = SMAT[n-1]* X0;
//    int ret = cum.mat[1][0];
//    return ret;
//}
int get_F(int f0, int f1, int n){

    matrix X0 = zero(2, 1);
    X0.mat[0][0] = f1;
    X0.mat[1][0] = f0;

    matrix F = (MAT[n]* X0);
    int ret = F.mat[1][0];
    return ret;
}
//
// fibo stuff end
//

//
// segment tree stuff begin
//
struct node{
    int val;
    int fst, scd;
};
//
#define stMax 1048576
node ST[stMax];
int GS, GE;
//
void init(){
    GS = 0, GE = n-1;
    for(int i=0; i<stMax; i++)
    {
        ST[i].val = 0;
        ST[i].fst = ST[i].scd = 0;
    }
}
void merge(int p){
    ST[p].val = ST[2*p].val;
    add(ST[p].val, ST[2*p+1].val);
}
void insert(int idx, int val, int s=GS, int e=GE, int p=1){

    if(s == e)
    {
        ST[p].val = val;
        return;
    }

    int m = (s+e)/2;
    if(idx <= m)
        insert(idx, val, s, m, 2*p);
    else
        insert(idx, val, m+1, e, 2*p+1);

    merge(p);
}
void update_node(int fst, int scd, int s, int e, int p){

    add(ST[p].fst, fst);

    add(ST[p].scd, scd);

    add(ST[p].val, query_F(fst, scd, e - s + 1));
}
void update_child(int s, int e, int p){
    int m = (s+e)/2;

    int f0 = ST[p].fst, f1 = ST[p].scd;
    update_node(f0, f1, s, m, 2*p);

    int k = m - s;
    int fkplus1 = get_F(f0, f1, k+1);
    int fkplus2 = get_F(f0, f1, k+2);
    update_node(fkplus1, fkplus2, m+1, e, 2*p+1);

    ST[p].fst = ST[p].scd = 0;
}
void update(int fr, int to, int fst, int scd, int s=GS, int e=GE, int p=1){

    if(fr <= s && e <= to)
    {
        update_node(fst, scd, s, e, p);
        return;
    }

    update_child(s, e, p);

    int m = (s+e)/2;
    if(to <= m)
        update(fr, to, fst, scd, s, m, 2*p);
    else if(fr >= m+1)
        update(fr, to, fst, scd, m+1, e, 2*p+1);
    else
    {
        update(fr, to, fst, scd, s, m, 2*p);

        // f0           f1              f2              ...             fl
        // max(fr, s)   ...             ...             ...             min(to, e)
        // m is included in [max(fr, s), min(to, e)] and opposite to fk

        int k = m - max(fr, s);
        int fkplus1 = get_F(fst, scd, k+1);
        int fkplus2 = get_F(fst, scd, k+2);

        update(fr, to, fkplus1, fkplus2, m+1, e, 2*p+1);
    }

    merge(p);
}
void update1(int fr, int to, int s=GS, int e=GE, int p=1){

    if(fr <= s && e <= to)
    {
        int f0 = get_F(0, 1, s - fr + 1);
        int f1 = get_F(0, 1, s - fr + 1 + 1);
        update_node(f0, f1, s, e, p);
        return;
    }

    update_child(s, e, p);

    int m = (s+e)/2;
    if(to <= m)
        update1(fr, to, s, m, 2*p);
    else if(fr >= m+1)
        update1(fr, to, m+1, e, 2*p+1);
    else
    {
        update1(fr, to, s, m, 2*p);
        update1(fr, to, m+1, e, 2*p+1);
    }

    merge(p);
}
int query(int fr, int to, int s=GS, int e=GE, int p=1){

    if(fr <= s && e <= to)
        return ST[p].val;

    update_child(s, e, p);

    int m = (s+e)/2;
    if(to <= m)
        return query(fr, to, s, m, 2*p);
    else if(fr >= m+1)
        return query(fr, to, m+1, e, 2*p+1);
    else
    {
        int ql = query(fr, to, s, m, 2*p);
        int qr = query(fr, to, m+1, e, 2*p+1);

        int ret = ql;
        add(ret, qr);
        return ret;
    }
}
//
// segment tree stuff end
//

int main()
{
    read_file();
    build();
    while(scanf("%d%d", &n, &nq)!=EOF)
    {
        init();
        for(int i=0; i<n; i++)
        {
            int x;
            scanf("%d", &x);
            insert(i, x);
        }

        while(nq--)
        {
            int cmd, fr, to;
            scanf("%d%d%d", &cmd, &fr, &to);
            fr--, to--;

            if(cmd == 1)
            {
                update(fr, to, 1, 1);
//                update1(fr, to);
                continue;
            }

            int ans;
            ans = query(fr, to);

            printf("%d\n", ans);
        }
        printf("\n");
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <ii> vii;
typedef vector <vii> vvii;
#define endl '\n'
#define PB push_back
#define MP make_pair
#define OO (1000000000)         // ToDo
#define EPS (1e-9)              // ToDo
#define MOD (1000000009)        // ToDo
#define all(v) ((v).begin()),((v).end())
#define DEBUG(x) cout<< #x <<" = "<<"\""<< (x) <<"\""<<endl
#define FASTIO ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
void read_file(bool outToFile = true){
#ifdef LOCAL_TEST
    freopen("in.in", "rt", stdin);
    if(outToFile)
    freopen("out.out", "wt", stdout);
#endif
}
//
#define nMax 300000+2+1
int n, nq;
//
inline void add(int &x, int v){
    x += v;
    if(x >= MOD) x -= MOD;
}
//

//
// fibo stuff begin
//
const int matMax = 2;
struct matrix{
    int n, m;
    int mat[matMax][matMax];

    matrix(){

    }

    matrix(int nn, int nm, int d=0){
        n = nn, m = nm;
        memset(mat, 0, sizeof mat);

        if(d)
        {
            for(int i=0; i<n; i++)
                mat[i][i] = d;
        }
    }

    matrix operator+ (const matrix &B) const{
        assert(n == B.n && m == B.m);

        matrix C = *this;
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
                add(C.mat[i][j], B.mat[i][j]);

        return C;
    }

    matrix operator* (const matrix &B) const{
        int p = B.m;
        assert(B.n == m);

        matrix C(n, p);
        for(int i=0; i<n; i++)
        {
            for(int k=0; k<m; k++)
            {
                if(mat[i][k] == 0) continue;
                for(int j=0; j<p; j++)
                    add(C.mat[i][j], 1LL * mat[i][k] * B.mat[k][j] %MOD);
            }
        }
        return C;
    }

    matrix operator* (const int &a) const{
        matrix ret(n, m);
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
                ret.mat[i][j] = mat[i][j] * a;
        return ret;
    }
};
//
matrix MAT[nMax];
matrix SMAT[nMax];
matrix T;
//
void build(){

    T = matrix(2, 2);
    T.mat[0][0] = 1;
    T.mat[0][1] = 1;
    T.mat[1][0] = 1;
    T.mat[1][1] = 0;

    MAT[0] = matrix(2, 2, 1);
    SMAT[0] = matrix(2, 2, 1);

    for(int i=1; i<nMax; i++)
    {
        MAT[i] = MAT[i-1] * T;
        SMAT[i] = SMAT[i-1] + MAT[i];
    }
}
int query_F(int f0, int f1, int n){

    matrix X0(2, 1);
    X0.mat[0][0] = f1;
    X0.mat[1][0] = f0;

    matrix cum = SMAT[n-1]* X0;
    int ret = cum.mat[1][0];
    return ret;
}
int get_F(int f0, int f1, int n){

    matrix X0(2, 1);
    X0.mat[0][0] = f1;
    X0.mat[1][0] = f0;

    matrix F = MAT[n] * X0;
    int ret = F.mat[1][0];
    return ret;
}
//
// fibo stuff end
//

//
// segment tree stuff begin
//
struct node{
    int val;
    int fst, scd;
};
//
#define stMax 1048576
node ST[stMax];
int GS, GE;
//
void init(){
    GS = 0, GE = n-1;
    for(int i=0; i<stMax; i++)
    {
        ST[i].val = 0;
        ST[i].fst = ST[i].scd = 0;
    }
}
void merge(int p){
    ST[p].val = ST[p<<1].val;
    add(ST[p].val, ST[p<<1|1].val);
}
void insert(int idx, int val, int s=GS, int e=GE, int p=1){

    if(s == e)
    {
        ST[p].val = val;
        return;
    }

    int m = s+e>>1;
    if(idx <= m)
        insert(idx, val, s, m, p<<1);
    else
        insert(idx, val, m+1, e, p<<1|1);

    merge(p);
}
void update_node(int fst, int scd, int s, int e, int p){

    add(ST[p].fst, fst);

    add(ST[p].scd, scd);

    add(ST[p].val, query_F(fst, scd, e - s + 1));
}
void update_child(int s, int e, int p){
    int m = s+e>>1;

    int f0 = ST[p].fst, f1 = ST[p].scd;
    update_node(f0, f1, s, m, p<<1);

    int k = m - s;
    int fkplus1 = get_F(f0, f1, k+1);
    int fkplus2 = get_F(f0, f1, k+2);
    update_node(fkplus1, fkplus2, m+1, e, p<<1|1);

    ST[p].fst = ST[p].scd = 0;
}
void update(int fr, int to, int fst, int scd, int s=GS, int e=GE, int p=1){

    if(fr <= s && e <= to)
    {
        update_node(fst, scd, s, e, p);
        return;
    }

    update_child(s, e, p);

    int m = s+e>>1;
    if(to <= m)
        update(fr, to, fst, scd, s, m, p<<1);
    else if(fr >= m+1)
        update(fr, to, fst, scd, m+1, e, p<<1|1);
    else
    {
        update(fr, to, fst, scd, s, m, p<<1);

        // f0           f1              f2              ...             fl
        // max(fr, s)   ...             ...             ...             min(to, e)
        // m is included in [max(fr, s), min(to, e)] and opposite to fk

        int k = m - max(fr, s);
        int fkplus1 = get_F(fst, scd, k+1);
        int fkplus2 = get_F(fst, scd, k+2);

        update(fr, to, fkplus1, fkplus2, m+1, e, p<<1|1);
    }

    merge(p);
}
void update1(int fr, int to, int s=GS, int e=GE, int p=1){

    if(fr <= s && e <= to)
    {
        int f0 = get_F(0, 1, s - fr + 1);
        int f1 = get_F(0, 1, s - fr + 1 + 1);
        update_node(f0, f1, s, e, p);
        return;
    }

    update_child(s, e, p);

    int m = (s+e)/2;
    if(to <= m)
        update1(fr, to, s, m, 2*p);
    else if(fr >= m+1)
        update1(fr, to, m+1, e, 2*p+1);
    else
    {
        update1(fr, to, s, m, 2*p);
        update1(fr, to, m+1, e, 2*p+1);
    }

    merge(p);
}
int query(int fr, int to, int s=GS, int e=GE, int p=1){

    if(fr <= s && e <= to)
        return ST[p].val;

    update_child(s, e, p);

    int m = s+e>>1;
    if(to <= m)
        return query(fr, to, s, m, p<<1);
    else if(fr >= m+1)
        return query(fr, to, m+1, e, p<<1|1);
    else
    {
        int ql = query(fr, to, s, m, p<<1);
        int qr = query(fr, to, m+1, e, p<<1|1);

        int ret = ql;
        add(ret, qr);
        return ret;
    }
}
//
// segment tree stuff end
//

int main()
{
    read_file();
    build();
    while(scanf("%d%d", &n, &nq)!=EOF)
    {
        init();
        for(int i=0; i<n; i++)
        {
            int x;
            scanf("%d", &x);
            insert(i, x);
        }

        while(nq--)
        {
            int cmd, fr, to;
            scanf("%d%d%d", &cmd, &fr, &to);
            fr--, to--;

            if(cmd == 1)
            {
                update(fr, to, 1, 1);
//                update1(fr, to);
                continue;
            }

            int ans;
            ans = query(fr, to);

            printf("%d\n", ans);
        }
        printf("\n");
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <ii> vii;
typedef vector <vii> vvii;
#define endl '\n'
#define PB push_back
#define MP make_pair
#define OO (1000000000)         // ToDo
#define EPS (1e-9)              // ToDo
#define MOD (1000000009)        // ToDo
#define all(v) ((v).begin()),((v).end())
#define DEBUG(x) cout<< #x <<" = "<<"\""<< (x) <<"\""<<endl
#define FASTIO ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
void read_file(bool outToFile = true){
#ifdef LOCAL_TEST
    freopen("in.in", "rt", stdin);
    if(outToFile)
    freopen("out.out", "wt", stdout);
#endif
}
//
#define nMax 300000+2+1
int n, nq;
//
void add(int &x, int v){
    x += v;
    if(x >= MOD) x -= MOD;
}
//

//
// fibo stuff begin
//
int MAT[nMax][2][2];
int SMAT[nMax][2][2];
int T[2][2];
//
void zero(int A[2][2]){
    for(int i=0; i<2; i++)
        for(int j=0; j<2; j++)
            A[i][j] = 0;
}
void identity(int A[2][2]){
    zero(A);
    for(int i=0; i<2; i++)
        A[i][i] = 1;
}
void mult(int A[2][2], int B[2][2], int C[2][2]){
    zero(C);
    for(int i=0; i<2; i++)
    {
        for(int j=0; j<2; j++)
        {
            for(int k=0; k<2; k++)
            {
                add(C[i][j], 1LL * A[i][k] * B[k][j] %MOD);
            }
        }
    }
}
void add(int A[2][2], int B[2][2], int C[2][2]){
    zero(C);
    for(int i=0; i<2; i++)
    {
        for(int j=0; j<2; j++)
        {
            C[i][j] = A[i][j];
            add(C[i][j], B[i][j]);
        }
    }
}
//
void build(){

    zero(T);
    T[0][0] = 1;
    T[0][1] = 1;
    T[1][0] = 1;
    T[1][1] = 0;

    identity(MAT[0]);
    identity(SMAT[0]);

    for(int i=1; i<nMax; i++)
    {
        mult(MAT[i-1], T, MAT[i]);
        add(SMAT[i-1], MAT[i], SMAT[i]);
    }
}
int query_F(int f0, int f1, int n){
    int a = SMAT[n-1][1][0];
    int b = SMAT[n-1][1][1];

    int ret = 1LL * a * f1 %MOD;
    add(ret, 1LL * b * f0 %MOD);
    return ret;
}
int get_F(int f0, int f1, int n){
    int a = MAT[n][1][0];
    int b = MAT[n][1][1];

    int ret = 1LL * a * f1 %MOD;
    add(ret, 1LL * b * f0 %MOD);
    return ret;
}
//
// fibo stuff end
//

//
// segment tree stuff begin
//
struct node{
    int val;
    int fst, scd;
};
//
#define stMax 1048576
node ST[stMax];
int GS, GE;
//
void init(){
    GS = 0, GE = n-1;
    for(int i=0; i<stMax; i++)
    {
        ST[i].val = 0;
        ST[i].fst = ST[i].scd = 0;
    }
}
void merge(int p){
    ST[p].val = ST[2*p].val;
    add(ST[p].val, ST[2*p+1].val);
}
void insert(int idx, int val, int s=GS, int e=GE, int p=1){

    if(s == e)
    {
        ST[p].val = val;
        return;
    }

    int m = (s+e)/2;
    if(idx <= m)
        insert(idx, val, s, m, 2*p);
    else
        insert(idx, val, m+1, e, 2*p+1);

    merge(p);
}
void update_node(int fst, int scd, int s, int e, int p){

    add(ST[p].fst, fst);

    add(ST[p].scd, scd);

    add(ST[p].val, query_F(fst, scd, e - s + 1));
}
void update_child(int s, int e, int p){
    int m = (s+e)/2;

    int f0 = ST[p].fst, f1 = ST[p].scd;
    update_node(f0, f1, s, m, 2*p);

    int k = m - s;
    int fkplus1 = get_F(f0, f1, k+1);
    int fkplus2 = get_F(f0, f1, k+2);
    update_node(fkplus1, fkplus2, m+1, e, 2*p+1);

    ST[p].fst = ST[p].scd = 0;
}
void update(int fr, int to, int fst, int scd, int s=GS, int e=GE, int p=1){

    if(fr <= s && e <= to)
    {
        update_node(fst, scd, s, e, p);
        return;
    }

    update_child(s, e, p);

    int m = (s+e)/2;
    if(to <= m)
        update(fr, to, fst, scd, s, m, 2*p);
    else if(fr >= m+1)
        update(fr, to, fst, scd, m+1, e, 2*p+1);
    else
    {
        update(fr, to, fst, scd, s, m, 2*p);

        // f0           f1              f2              ...             fl
        // max(fr, s)   ...             ...             ...             min(to, e)
        // m is included in [max(fr, s), min(to, e)] and opposite to fk

        int k = m - max(fr, s);
        int fkplus1 = get_F(fst, scd, k+1);
        int fkplus2 = get_F(fst, scd, k+2);

        update(fr, to, fkplus1, fkplus2, m+1, e, 2*p+1);
    }

    merge(p);
}
void update1(int fr, int to, int s=GS, int e=GE, int p=1){

    if(fr <= s && e <= to)
    {
        int f0 = get_F(0, 1, s - fr + 1);
        int f1 = get_F(0, 1, s - fr + 1 + 1);
        update_node(f0, f1, s, e, p);
        return;
    }

    update_child(s, e, p);

    int m = (s+e)/2;
    if(to <= m)
        update1(fr, to, s, m, 2*p);
    else if(fr >= m+1)
        update1(fr, to, m+1, e, 2*p+1);
    else
    {
        update1(fr, to, s, m, 2*p);
        update1(fr, to, m+1, e, 2*p+1);
    }

    merge(p);
}
int query(int fr, int to, int s=GS, int e=GE, int p=1){

    if(fr <= s && e <= to)
        return ST[p].val;

    update_child(s, e, p);

    int m = (s+e)/2;
    if(to <= m)
        return query(fr, to, s, m, 2*p);
    else if(fr >= m+1)
        return query(fr, to, m+1, e, 2*p+1);
    else
    {
        int ql = query(fr, to, s, m, 2*p);
        int qr = query(fr, to, m+1, e, 2*p+1);

        int ret = ql;
        add(ret, qr);
        return ret;
    }
}
//
// segment tree stuff end
//

int main()
{
    read_file();
    build();
    while(scanf("%d%d", &n, &nq)!=EOF)
    {
        init();
        for(int i=0; i<n; i++)
        {
            int x;
            scanf("%d", &x);
            insert(i, x);
        }

        while(nq--)
        {
            int cmd, fr, to;
            scanf("%d%d%d", &cmd, &fr, &to);
            fr--, to--;

            if(cmd == 1)
            {
                update(fr, to, 1, 1);
//                update1(fr, to);
                continue;
            }

            int ans;
            ans = query(fr, to);

            printf("%d\n", ans);
        }
        printf("\n");
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <ii> vii;
typedef vector <vii> vvii;
#define endl '\n'
#define PB push_back
#define MP make_pair
#define OO (1000000000)         // ToDo
#define EPS (1e-9)              // ToDo
#define MOD (1000000009)        // ToDo
#define all(v) ((v).begin()),((v).end())
#define DEBUG(x) cout<< #x <<" = "<<"\""<< (x) <<"\""<<endl
#define FASTIO ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
void read_file(bool outToFile = true){
#ifdef LOCAL_TEST
    freopen("in.in", "rt", stdin);
    if(outToFile)
    freopen("out.out", "wt", stdout);
#endif
}
//
#define nMax 300000+2+1
int n, nq;
//
void add(int &x, int v){
    x += v;
    if(x >= MOD) x -= MOD;
}
//

//
// fibo stuff begin
//
const int matMax = 2;
struct matrix{
    int n, m;
    int mat[matMax][matMax];
    matrix(int nn=0, int nm=0, int d=0){
        n = nn, m = nm;
        memset(mat, 0, sizeof mat);

        if(d)
        {
            for(int i=0; i<n; i++)
                mat[i][i] = d;
        }
    }

    matrix operator+ (const matrix &B) const{
        assert(n == B.n && m == B.m);

        matrix C = *this;
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
                add(C.mat[i][j], B.mat[i][j]);

        return C;
    }

    matrix operator* (const matrix &B) const{
        int p = B.m;
        assert(B.n == m);

        matrix C(n, p);
        for(int i=0; i<n; i++)
        {
            for(int k=0; k<m; k++)
            {
                if(mat[i][k] == 0) continue;
                for(int j=0; j<p; j++)
                    add(C.mat[i][j], 1LL * mat[i][k] * B.mat[k][j] %MOD);
            }
        }
        return C;
    }
};
matrix MAT[nMax];
matrix SMAT[nMax];
matrix T;
//
//matrix operator+ (const matrix &A, const matrix &B){
//    int n, m;
//    n = A.n, m = A.m;
//    assert(n == B.n && m == B.m);
//
//    matrix C = A;
//    for(int i=0; i<n; i++)
//        for(int j=0; j<m; j++)
//            add(C.mat[i][j], B.mat[i][j]);
//
//    return C;
//}
//matrix operator* (const matrix &A, const matrix &B){
//    int n, m, p;
//    n = A.n;
//    m = A.m;
//    p = B.m;
//    assert(B.n == m);
//
//    matrix C(n, p);
//    for(int i=0; i<n; i++)
//    {
//        for(int k=0; k<m; k++)
//        {
//            if(A.mat[i][k] == 0) continue;
//            for(int j=0; j<p; j++)
//                add(C.mat[i][j], 1LL * A.mat[i][k] * B.mat[k][j] %MOD);
//        }
//    }
//    return C;
//}
//
void build(){

    T = matrix(2, 2);
    T.mat[0][0] = 1;
    T.mat[0][1] = 1;
    T.mat[1][0] = 1;
    T.mat[1][1] = 0;

    MAT[0] = matrix(2, 2, 1);
    SMAT[0] = matrix(2, 2, 1);

    for(int i=1; i<nMax; i++)
    {
        MAT[i] = MAT[i-1] * T;
        SMAT[i] = SMAT[i-1] + MAT[i];
    }
}
int query_F(int f0, int f1, int n){
    int a = SMAT[n-1].mat[1][0];
    int b = SMAT[n-1].mat[1][1];

    int ret = 1LL * a * f1 %MOD;
    add(ret, 1LL * b * f0 %MOD);
    return ret;
}
//int query_F(int f0, int f1, int n){
//
//    matrix X0(2, 1);
//    X0.mat[0][0] = f1;
//    X0.mat[1][0] = f0;
//
//    matrix cum = SMAT[n-1]* X0;
//    int ret = cum.mat[1][0];
//    return ret;
//}
int get_F(int f0, int f1, int n){

    matrix X0(2, 1);
    X0.mat[0][0] = f1;
    X0.mat[1][0] = f0;

    matrix F = MAT[n] * X0;
    int ret = F.mat[1][0];
    return ret;
}
//
// fibo stuff end
//

//
// segment tree stuff begin
//
struct node{
    int val;
    int fst, scd;
};
//
#define stMax 1048576
node ST[stMax];
int GS, GE;
//
void init(){
    GS = 0, GE = n-1;
    for(int i=0; i<stMax; i++)
    {
        ST[i].val = 0;
        ST[i].fst = ST[i].scd = 0;
    }
}
void merge(int p){
    ST[p].val = ST[2*p].val;
    add(ST[p].val, ST[2*p+1].val);
}
void insert(int idx, int val, int s=GS, int e=GE, int p=1){

    if(s == e)
    {
        ST[p].val = val;
        return;
    }

    int m = (s+e)/2;
    if(idx <= m)
        insert(idx, val, s, m, 2*p);
    else
        insert(idx, val, m+1, e, 2*p+1);

    merge(p);
}
void update_node(int fst, int scd, int s, int e, int p){

    add(ST[p].fst, fst);

    add(ST[p].scd, scd);

    add(ST[p].val, query_F(fst, scd, e - s + 1));
}
void update_child(int s, int e, int p){
    int m = (s+e)/2;

    int f0 = ST[p].fst, f1 = ST[p].scd;
    update_node(f0, f1, s, m, 2*p);

    int k = m - s;
    int fkplus1 = get_F(f0, f1, k+1);
    int fkplus2 = get_F(f0, f1, k+2);
    update_node(fkplus1, fkplus2, m+1, e, 2*p+1);

    ST[p].fst = ST[p].scd = 0;
}
void update(int fr, int to, int fst, int scd, int s=GS, int e=GE, int p=1){

    if(fr <= s && e <= to)
    {
        update_node(fst, scd, s, e, p);
        return;
    }

    update_child(s, e, p);

    int m = (s+e)/2;
    if(to <= m)
        update(fr, to, fst, scd, s, m, 2*p);
    else if(fr >= m+1)
        update(fr, to, fst, scd, m+1, e, 2*p+1);
    else
    {
        update(fr, to, fst, scd, s, m, 2*p);

        // f0           f1              f2              ...             fl
        // max(fr, s)   ...             ...             ...             min(to, e)
        // m is included in [max(fr, s), min(to, e)] and opposite to fk

        int k = m - max(fr, s);
        int fkplus1 = get_F(fst, scd, k+1);
        int fkplus2 = get_F(fst, scd, k+2);

        update(fr, to, fkplus1, fkplus2, m+1, e, 2*p+1);
    }

    merge(p);
}
void update1(int fr, int to, int s=GS, int e=GE, int p=1){

    if(fr <= s && e <= to)
    {
        int f0 = get_F(0, 1, s - fr + 1);
        int f1 = get_F(0, 1, s - fr + 1 + 1);
        update_node(f0, f1, s, e, p);
        return;
    }

    update_child(s, e, p);

    int m = (s+e)/2;
    if(to <= m)
        update1(fr, to, s, m, 2*p);
    else if(fr >= m+1)
        update1(fr, to, m+1, e, 2*p+1);
    else
    {
        update1(fr, to, s, m, 2*p);
        update1(fr, to, m+1, e, 2*p+1);
    }

    merge(p);
}
int query(int fr, int to, int s=GS, int e=GE, int p=1){

    if(fr <= s && e <= to)
        return ST[p].val;

    update_child(s, e, p);

    int m = (s+e)/2;
    if(to <= m)
        return query(fr, to, s, m, 2*p);
    else if(fr >= m+1)
        return query(fr, to, m+1, e, 2*p+1);
    else
    {
        int ql = query(fr, to, s, m, 2*p);
        int qr = query(fr, to, m+1, e, 2*p+1);

        int ret = ql;
        add(ret, qr);
        return ret;
    }
}
//
// segment tree stuff end
//

int main()
{
    read_file();
    build();
    while(scanf("%d%d", &n, &nq)!=EOF)
    {
        init();
        for(int i=0; i<n; i++)
        {
            int x;
            scanf("%d", &x);
            insert(i, x);
        }

        while(nq--)
        {
            int cmd, fr, to;
            scanf("%d%d%d", &cmd, &fr, &to);
            fr--, to--;

            if(cmd == 1)
            {
                update(fr, to, 1, 1);
//                update1(fr, to);
                continue;
            }

            int ans;
            ans = query(fr, to);

            printf("%d\n", ans);
        }
        printf("\n");
    }
}


#include<iostream>
#include<cstdio>
#define LL long long
#define mid ((l+r)>>1)
#define lson (k<<1)
#define rson ((k<<1)|1)
using namespace std;
int n, m, opt, l, r, x;
const int N = 300010, mod = 1e9 + 9;
int f[N], tr[N << 2], lazy1[N << 2], lazy2[N << 2];
inline int read()
{
	int res = 0; char ch = getchar(); bool XX = false;
	for (; !isdigit(ch); ch = getchar())(ch == '-') && (XX = true);
	for (; isdigit(ch); ch = getchar())res = (res << 3) + (res << 1) + (ch ^ 48);
	return XX ? -res : res;
}
void build(int k, int l, int r)
{
	if (l == r)
	{
		tr[k] = read();
		return;
	}
	build(lson, l, mid);
	build(rson, mid + 1, r);
	tr[k] = (tr[lson] + tr[rson]) % mod;
}
void add(int k, int l, int r, int a, int b)
{
	lazy1[k] = (lazy1[k] + a) % mod;
	lazy2[k] = (lazy2[k] + b) % mod;
	(tr[k] += 1LL*a * f[r - l + 1] % mod + 1LL*b * f[r - l + 2] % mod - b ) %= mod;
}
void cd(int k, int l, int r)
{
	int lina, linb;
	if (lazy1[k])
	{
		lina = (1LL*lazy1[k] * f[mid - l] % mod + 1LL*lazy2[k] * f[mid - l + 1] % mod) % mod;
		linb = (1LL*lazy1[k] * f[mid - l + 1] % mod + 1LL*lazy2[k] * f[mid - l + 2] % mod) % mod;
		add(lson, l, mid, lazy1[k], lazy2[k]);
		add(rson, mid + 1, r, lina, linb);
		lazy1[k] = lazy2[k] = 0;
	}
}
int ask(int k, int l, int r, int x, int y)
{
	if (x <= l && r <= y)return tr[k];
	cd(k, l, r);
	int res = 0;
	if (x <= mid)(res += ask(lson, l, mid, x, y)) %= mod;
	if (mid + 1 <= y)(res += ask(rson, mid + 1, r, x, y)) %= mod;
	return res;
}
void change(int k, int l, int r, int x, int y)
{
	if (x <= l && r <= y)
	{
		add(k, l, r, f[l - x + 1], f[l - x + 2]);
		return;
	}
	if (x <= mid)change(lson, l, mid, x, y);
	if (mid + 1 <= r)change(rson, mid + 1, r, x, y);
	tr[k] = (tr[lson] + tr[rson]) % mod;
}
signed main()
{
	cin >> n >> m;
	f[1] = 1;
	for (int i = 2; i <= 300001; ++i)f[i] = (f[i - 1] + f[i - 2]) % mod;
	build(1, 1, n);
	while (m--)
	{
		opt = read(); l = read(); r = read();
		if (!(opt & 1))printf("%d\n", ask(1, 1, n, l, r));
		else change(1, 1, n, l, r);
	}
	fclose(stdin); fclose(stdout);
	return 0;
}
/*
10 10
0 0 0 0 0 0 0 0 0 0
2 5 6 10
1 1 9
*/


#include<iostream>
#include<cstdio>
#define int long long
#define mid ((l+r)>>1)
#define lson (k<<1)
#define rson ((k<<1)|1)
using namespace std;
int n,m,opt,l,r,x;
const int N=300010,mod=1e9+9;
int f[N],tr[N<<2],lazy1[N<<2],lazy2[N<<2];
inline int read()
{
    int res=0;char ch=getchar();bool XX=false;
    for(;!isdigit(ch);ch=getchar())(ch=='-') && (XX=true);
    for(;isdigit(ch);ch=getchar())res=(res<<3)+(res<<1)+(ch^48);
    return XX?-res:res;
}
void build(int k,int l,int r)
{
	if(l==r)
	{
		tr[k]=read();
		return;
	}
	build(lson,l,mid);
	build(rson,mid+1,r);
	tr[k]=tr[lson]+tr[rson];
}
int my_mod(int x){return x>mod?x-mod:x;}
void add(int k,int l,int r,int a,int b)
{
	lazy1[k]=my_mod(lazy1[k]+a);
	lazy2[k]=my_mod(lazy2[k]+b);
	(tr[k]+=a*f[r-l+1]%mod+b*f[r-l+2]%mod-b)%=mod;
}
void cd(int k,int l,int r)
{
	int lina,linb;
	if(lazy1[k])
	{
		lina=(lazy1[k]*f[mid-l]%mod+lazy2[k]*f[mid-l+1]%mod)%mod;
		linb=(lazy1[k]*f[mid-l+1]%mod+lazy2[k]*f[mid-l+2]%mod)%mod;
		add(lson,l,mid,lazy1[k],lazy2[k]);
		add(rson,mid+1,r,lina,linb);
		lazy1[k]=lazy2[k]=0;
	}
}
int ask(int k,int l,int r,int x,int y)
{
	if(x<=l&&r<=y)return tr[k];
	cd(k,l,r);
	int res=0;
	if(x<=mid)(res+=ask(lson,l,mid,x,y))%=mod;
	if(mid+1<=y)(res+=ask(rson,mid+1,r,x,y))%=mod;
	return res;
}
void change(int k,int l,int r,int x,int y)
{
	if(x<=l&&r<=y)
	{
		add(k,l,r,f[l-x+1],f[l-x+2]);
		return;
	}
	if(x<=mid)change(lson,l,mid,x,y);
	if(mid+1<=r)change(rson,mid+1,r,x,y);
	tr[k]=(tr[lson]+tr[rson])%mod;
}
signed main()
{
	cin>>n>>m;
	f[1]=1;
	for(int i=2;i<=200000;++i)f[i]=(f[i-1]+f[i-2])%mod;
	build(1,1,n);
	while(m--)
	{
		opt=read();l=read();r=read();
		if(!(opt&1))printf("%lld\n",ask(1,1,n,l,r));
		else change(1,1,n,l,r);
	}
	fclose(stdin);fclose(stdout);
	return 0;
}
/*
10 10
0 0 0 0 0 0 0 0 0 0
2 5 6 10
1 1 9
*/


#include<iostream>
#include<cstdio>
#define int long long
#define LL long long
#define mid ((l+r)>>1)
#define lson (k<<1)
#define rson ((k<<1)|1)
using namespace std;
int n, m, opt, l, r, x;
const int N = 300010, mod = 1e9 + 9;
int f[N], tr[N << 2], lazy1[N << 2], lazy2[N << 2];
inline int read()
{
	int res = 0; char ch = getchar(); bool XX = false;
	for (; !isdigit(ch); ch = getchar())(ch == '-') && (XX = true);
	for (; isdigit(ch); ch = getchar())res = (res << 3) + (res << 1) + (ch ^ 48);
	return XX ? -res : res;
}
void build(int k, int l, int r)
{
	if (l == r)
	{
		tr[k] = read();
		return;
	}
	build(lson, l, mid);
	build(rson, mid + 1, r);
	tr[k] = (tr[lson] + tr[rson]) % mod;
}
void add(int k, int l, int r, int a, int b)
{
	lazy1[k] = (lazy1[k] + a) % mod;
	lazy2[k] = (lazy2[k] + b) % mod;
	(tr[k] += 1LL*a * f[r - l + 1] % mod + 1LL*b * f[r - l + 2] % mod - b +mod) %= mod;
}
void cd(int k, int l, int r)
{
	int lina, linb;
	if (lazy1[k])
	{
		lina = (1LL*lazy1[k] * f[mid - l] % mod + 1LL*lazy2[k] * f[mid - l + 1] % mod) % mod;
		linb = (1LL*lazy1[k] * f[mid - l + 1] % mod + 1LL*lazy2[k] * f[mid - l + 2] % mod) % mod;
		add(lson, l, mid, lazy1[k], lazy2[k]);
		add(rson, mid + 1, r, lina, linb);
		lazy1[k] = lazy2[k] = 0;
	}
}
int ask(int k, int l, int r, int x, int y)
{
	if (x <= l && r <= y)return tr[k];
	cd(k, l, r);
	int res = 0;
	if (x <= mid)(res += ask(lson, l, mid, x, y)) %= mod;
	if (mid + 1 <= y)(res += ask(rson, mid + 1, r, x, y)) %= mod;
	return res;
}
void change(int k, int l, int r, int x, int y)
{//cout<<k<<" "<<l<<" "<<r<<" "<<x<<" "<<y<<endl;getchar();
	if (x <= l && r <= y)
	{
		add(k, l, r, f[l - x + 1], f[l - x + 2]);
		return;
	}
	cd(k,l,r);
	if (x <= mid)change(lson, l, mid, x, y);
	if (mid + 1 <= y)change(rson, mid + 1, r, x, y);
	tr[k] = (tr[lson] + tr[rson]) % mod;
}
signed main()
{
	cin >> n >> m;
	f[1] = 1;
	for (int i = 2; i <= 300001; ++i)f[i] = (f[i - 1] + f[i - 2]) % mod;
	build(1, 1, n);
	while (m--)
	{
		opt = read(); l = read(); r = read();
		if (!(opt & 1))printf("%lld\n", (ask(1, 1, n, l, r)%mod+mod)%mod);
		else change(1, 1, n, l, r);
	}
	fclose(stdin); fclose(stdout);
	return 0;
}
/*
5 4
0 0 0 0 0
1 1 1
1 1 3
1 2 2
2 1 4
*/


#include<iostream>
#include<vector>
#include<cstdio>
#define int long long
#define mid ((l+r)>>1)
#define lson (k<<1)
#define rson ((k<<1)|1)
using namespace std;
int n,m,opt,l,r,x;
const int N=200010,mod=1e9+7;
int f[N],sum[N],tr[N<<2];
vector<int>v[N];
inline int read()
{
    int res=0;char ch=getchar();bool XX=false;
    for(;!isdigit(ch);ch=getchar())(ch=='-') && (XX=true);
    for(;isdigit(ch);ch=getchar())res=(res<<3)+(res<<1)+(ch^48);
    return XX?-res:res;
}
void build(int k,int l,int r)
{
	if(l==r)
	{
		tr[k]=read();
		return;
	}
	build(lson,l,mid);
	build(rson,mid+1,r);
	tr[k]=tr[lson]+tr[rson];
}
void cd(int k,int l,int r)
{
	int p;
	for(int i=v[k].size()-1;i>=0;--i)
	{
		p=v[k][i];
		(tr[lson]+=sum[mid-l+p]-sum[p-1]+mod)%=mod;
		v[lson].push_back(p);
		(tr[rson]+=sum[r-l+p]-sum[mid-l+p]+mod)%=mod;
		v[rson].push_back(mid+1-l+p);
		v[k].pop_back();
	}
}
int ask(int k,int l,int r,int x,int y)
{
	if(x<=l&&r<=y)return tr[k];
	if(v[k].size())cd(k,l,r);
	int res=0;
	if(x<=mid)(res+=ask(lson,l,mid,x,y))%=mod;
	if(mid+1<=y)(res+=ask(rson,mid+1,r,x,y))%=mod;
	return res;
}
void change(int k,int l,int r,int x,int y,int p)
{
	if(l==x&&r==y)
	{
		(tr[k]+=sum[r-l+p]-sum[p-1]+mod)%=mod;
		v[k].push_back(p);
		return;
	}
	if(v[k].size())cd(k,l,r);
	if(y<=mid)change(lson,l,mid,x,y,p);
	else if(x>=mid+1)change(rson,mid+1,r,x,y,p);
	else change(lson,l,mid,x,mid,p),change(rson,mid+1,r,mid+1,y,mid+1-x+p);
	tr[k]=(tr[lson]+tr[rson])%mod;
}
void slove1()
{
	f[1]=1;
	for(int i=2;i<=200000;++i)f[i]=(f[i-1]+f[i-2])%mod;
	for(int i=1;i<=200000;++i)sum[i]=(sum[i-1]+f[i])%mod;
	build(1,1,n);
	while(m--)
	{
		opt=read();l=read();r=read();
		if(!(opt&1))
		{
			printf("%lld\n",ask(1,1,n,l,r));
		}
		else
		{
			change(1,1,n,l,r,1);
		}
	}
}
signed main()
{
	/*freopen("d.in","r",stdin);
	freopen("d.out","w",stdout);*/
	cin>>n>>m;
	slove1();
	fclose(stdin);fclose(stdout);
	return 0;
}
/*
10 10
0 0 0 0 0 0 0 0 0 0
2 5 6 10
1 1 9
*/


#include<iostream>
#include<cstdio>
#define int long long
#define LL long long
#define mid ((l+r)>>1)
#define lson (k<<1)
#define rson ((k<<1)|1)
using namespace std;
int n, m, opt, l, r, x;
const int N = 300010, mod = 1e9 + 9;
int f[N], tr[N << 2], lazy1[N << 2], lazy2[N << 2];
inline int read()
{
	int res = 0; char ch = getchar(); bool XX = false;
	for (; !isdigit(ch); ch = getchar())(ch == '-') && (XX = true);
	for (; isdigit(ch); ch = getchar())res = (res << 3) + (res << 1) + (ch ^ 48);
	return XX ? -res : res;
}
void build(int k, int l, int r)
{
	if (l == r)
	{
		tr[k] = read();
		return;
	}
	build(lson, l, mid);
	build(rson, mid + 1, r);
	tr[k] = (tr[lson] + tr[rson]) % mod;
}
void add(int k, int l, int r, int a, int b)
{
	lazy1[k] = (lazy1[k] + a) % mod;
	lazy2[k] = (lazy2[k] + b) % mod;
	(tr[k] += 1LL*a * f[r - l + 1] % mod + 1LL*b * f[r - l + 2] % mod - b ) %= mod;
}
void cd(int k, int l, int r)
{
	int lina, linb;
	if (lazy1[k])
	{
		lina = (1LL*lazy1[k] * f[mid - l] % mod + 1LL*lazy2[k] * f[mid - l + 1] % mod) % mod;
		linb = (1LL*lazy1[k] * f[mid - l + 1] % mod + 1LL*lazy2[k] * f[mid - l + 2] % mod) % mod;
		add(lson, l, mid, lazy1[k], lazy2[k]);
		add(rson, mid + 1, r, lina, linb);
		lazy1[k] = lazy2[k] = 0;
	}
}
int ask(int k, int l, int r, int x, int y)
{
	if (x <= l && r <= y)return tr[k];
	cd(k, l, r);
	int res = 0;
	if (x <= mid)(res += ask(lson, l, mid, x, y)) %= mod;
	if (mid + 1 <= y)(res += ask(rson, mid + 1, r, x, y)) %= mod;
	return res;
}
void change(int k, int l, int r, int x, int y)
{//cout<<k<<" "<<l<<" "<<r<<" "<<x<<" "<<y<<endl;getchar();
	if (x <= l && r <= y)
	{
		add(k, l, r, f[l - x + 1], f[l - x + 2]);
		return;
	}
	if (x <= mid)change(lson, l, mid, x, y);
	if (mid + 1 <= y)change(rson, mid + 1, r, x, y);
	tr[k] = (tr[lson] + tr[rson]) % mod;
}
signed main()
{
	cin >> n >> m;
	f[1] = 1;
	for (int i = 2; i <= 300001; ++i)f[i] = (f[i - 1] + f[i - 2]) % mod;
	build(1, 1, n);
	while (m--)
	{
		opt = read(); l = read(); r = read();
		if (!(opt & 1))printf("%lld\n", ask(1, 1, n, l, r));
		else change(1, 1, n, l, r);
	}
	fclose(stdin); fclose(stdout);
	return 0;
}
/*
10 3
0 0 0 0 0 0 0 0 0 0
2 5 6
2 6 7
1 1 1
*/


import math

class Read:
    @staticmethod
    def string():
        return input()

    @staticmethod
    def int():
        return int(input())

    @staticmethod
    def list(sep=' '):
        return input().split(sep)

    @staticmethod
    def list_int(sep=' '):
        return list(map(int, input().split(sep)))

def solve():
    n = Read.int()
    a = Read.list_int()
    new_a = list(filter(lambda x: x != -1, a))
    if len(new_a) == 0:
        print(0, 0)
        return
    k = round(sum(new_a)/len(new_a))

    m = 0
    for i in range(n - 1):
        p1 = a[i] if a[i] != -1 else k
        p2 = a[i + 1] if a[i + 1] != -1 else k
        r = math.fabs(p1 - p2)
        if r > m:
            m = int(r)
    print(m, k)

# query_count = 1
query_count = Read.int()
while query_count:
    query_count -= 1
    solve()


import math

class Read:
    @staticmethod
    def string():
        return input()

    @staticmethod
    def int():
        return int(input())

    @staticmethod
    def list(sep=' '):
        return input().split(sep)

    @staticmethod
    def list_int(sep=' '):
        return list(map(int, input().split(sep)))

def solve():
    n = Read.int()
    a = Read.list_int()

    new_a = []
    for i in range(n):
        if a[i] != -1 and (i == 0 or a[i - 1] != -1) and (i == n - 1 or a[i + 1] != -1):
            continue
        new_a.append(a[i])
    # print(new_a)
    new_a = list(filter(lambda x: x != -1, new_a))
    if len(new_a) == 0:
        print(0, 0)
        return
    k = round(sum(new_a)/len(new_a))

    m = 0
    for i in range(n - 1):
        p1 = a[i] if a[i] != -1 else k
        p2 = a[i + 1] if a[i + 1] != -1 else k
        r = math.fabs(p1 - p2)
        if r > m:
            m = int(r)
    print(m, k)

# query_count = 1
query_count = Read.int()
while query_count:
    query_count -= 1
    solve()


import math

class Read:
    @staticmethod
    def string():
        return input()

    @staticmethod
    def int():
        return int(input())

    @staticmethod
    def list(sep=' '):
        return input().split(sep)

    @staticmethod
    def list_int(sep=' '):
        return list(map(int, input().split(sep)))

def solve():
    n = Read.int()
    a = Read.list_int()

    new_a = []
    for i in range(n):
        if a[i] != -1 and (i == 0 or a[i - 1] != -1) and (i == n - 1 or a[i + 1] != -1):
            continue
        new_a.append(a[i])
    new_a = list(filter(lambda x: x != -1, new_a))
    if len(new_a) == 0:
        print('0 0')
        return
    mx = max(new_a)
    mn = min(new_a)
    k = round((mx + mn) / 2)
    m = 0
    for i in range(n - 1):
        p1 = a[i] if a[i] != -1 else k
        p2 = a[i + 1] if a[i + 1] != -1 else k
        r = math.fabs(p1 - p2)
        if r > m:
            m = int(r)
    print(m, k)

# query_count = 1
query_count = Read.int()
while query_count:
    query_count -= 1
    solve()


import math

class Read:
    @staticmethod
    def string():
        return input()

    @staticmethod
    def int():
        return int(input())

    @staticmethod
    def list(sep=' '):
        return input().split(sep)

    @staticmethod
    def list_int(sep=' '):
        return list(map(int, input().split(sep)))

def solve():
    n = Read.int()
    a = Read.list_int()
    last = None
    t = []
    for i in range(n - 1):
        if a[i] == -1:
            continue
        if last is not None:
            t.append(min(a[i], last) + (math.fabs(a[i] - last) // 2))
        last = a[i]
    if len(t) > 0:
        k = int(math.floor(sum(t)/len(t)))
    else:
        print(0, 0)
        return
    m = 0
    for i in range(n - 1):
        p1 = a[i] if a[i] != -1 else k
        p2 = a[i + 1] if a[i + 1] != -1 else k
        # print(p1, p2)
        r = math.fabs(p1 - p2)
        if r > m:
            m = int(r)
    print(m, k)

# query_count = 1
query_count = Read.int()
while query_count:
    query_count -= 1
    solve()


a=int(input())
for i in range(a):
    r=input()
    z=list(map(int,input().split()))
    t=[]
    for i in range(len(z)):
        if(z[i]==-1):
            if(i>0):
                if(z[i-1]!=-1):

                    t.append(z[i-1])
            if(i<len(z)-1):
                if(z[i+1]!=-1):

                    t.append(z[i+1])
    if(len(t)==0):
        k=0
    else:
        k=(max(t)+min(t))//2
    for i in range(len(z)):
        if(z[i]==-1):
            z[i]=k
    mini=0
    for i in range(1,len(z)):
        if(abs(z[i]-z[i-1])>mini):
            mini=abs(z[i]-z[i-1])

    print(mini,k)


a=int(input())
for i in range(a):
    r=input()
    z=list(map(int,input().split()))
    t=[]
    for i in range(len(z)):
        if(z[i]==-1):
            if(i>0):
                t.append(z[i-1])
            if(i<len(z)-1):
                t.append(z[i+1])
    k=(max(t)+min(t))//2
    for i in range(len(z)):
        if(z[i]==-1):
            z[i]=k
    mini=0
    for i in range(1,len(z)):
        if(z[i]-z[i-1]>mini):
            mini=abs(z[i]-z[i-1])

    print(mini,k)


a=int(input())
for i in range(a):
    r=input()
    z=list(map(int,input().split()))
    t=[]
    for i in range(len(z)):
        if(z[i]==-1):
            if(i>0):
                t.append(z[i-1])
            if(i<len(z)-1):
                t.append(z[i+1])
    k=(max(t)+min(t))//2
    for i in range(len(z)):
        if(z[i]==-1):
            z[i]=k
    mini=0
    for i in range(1,len(z)):
        if(abs(z[i]-z[i-1])>mini):
            mini=abs(z[i]-z[i-1])

    print(mini,k)


a=int(input())
for i in range(a):
    r=input()
    z=list(map(int,input().split()))
    t=[]
    for i in range(len(z)):
        if(z[i]==-1):
            if(i>0):
                if(z[i-1]!=-1):

                    t.append(z[i-1])
            if(i<len(z)-1):
                if(z[i+1]!=-1):

                    t.append(z[i+1])
    k=(max(t)+min(t))//2
    for i in range(len(z)):
        if(z[i]==-1):
            z[i]=k
    mini=0
    for i in range(1,len(z)):
        if(abs(z[i]-z[i-1])>mini):
            mini=abs(z[i]-z[i-1])

    print(mini,k)


t=int(input())
while t:
    t-=1
    n = int(input())
    a=list(map(int ,input().split()))
    ar = [-2]+a+[-2]
    r=[]# [*filter(lambda x,y,z: y==-1 and (x>-1 or y>-1), a)]
    for i in range(1,n+2):
        if ar[i]>-1 and (ar[i-1]==-1 or ar[i+1]==-1):
            r.append(ar[i])
    ans, m =0, 0
    if not r == []:
        ans=(max(r)+min(r))//2
        a = [*map(lambda x: ans if x==-1 else x, a)]
        m = max([abs(a[i]-a[i-1]) for i in range(1, n)])
    print(m, ans)


t=int(input())
while t:
    t-=1
    n = int(input())
    a = list(map(int ,input().split()))
    missing=a.count(-1)
    m,avg = 0 , 0
    if not missing == n:
        avg = (sum(a)-(-1)*missing)//(n-missing)
        m=max(a) - avg
    print(m, avg)


t=int(input())
while t:
    t-=1
    n = int(input())
    a = list(map(int ,input().split()))
    r= [*filter(lambda x: x>-1, a)]
    ans, m =0, 0
    if not r == []:
        ans=(max(a)+min(r))//2
        a = [*map(lambda x: ans if x==-1 else x, a)]
        m = max([abs(a[i]-a[i-1]) for i in range(1, n)])
    print(m, ans)


t=int(input())
while t:
    t-=1
    n = int(input())
    a = [-2]+list(map(int ,input().split()))+[-2]
    r=[]# [*filter(lambda x,y,z: y==-1 and (x>-1 or y>-1), a)]
    for i in range(n+2):
        if a[i]>-1 and (a[i-1]==-1 or a[i+1]==-1):
            r.append(a[i])
    ans, m =0, 0
    if not r == []:
        ans=(max(r)+min(r))//2
        a = [*map(lambda x: ans if x==-1 else x, a)]
        m = max([abs(a[i]-a[i-1]) for i in range(1, n)])
    print(m, ans)


t=int(input())
while t:
    t-=1
    n = int(input())
    a = list(map(int ,input().split()))
    missing=a.count(-1)
    m,avg = 0 , 0
    if not missing == n:
        avg = (sum(a)-(-1)*missing)//(n-missing)
        a = [*map(lambda x: avg if x==-1 else x, a)]
        m = max([abs(a[i]-a[i-1]) for i in range(1, n)])
    print(m, avg)


t=int(input())
while t:
    t-=1
    n = int(input())
    a=list(map(int ,input().split()))
    ar = [-2]+a+[-2]
    r=[]# [*filter(lambda x,y,z: y==-1 and (x>-1 or y>-1), a)]
    for i in range(1,n+2):
        if ar[i]>-1 and (ar[i-1]==-1 or ar[i+1]==-1):
            r.append(ar[i])
    ans, m =0, 0
    if not r == []:
        #ans=(max(r)+min(r))//2
        ans = sum(r)//len(r)
        a = [*map(lambda x: ans if x==-1 else x, a)]
        m = max([abs(a[i]-a[i-1]) for i in range(1, n)])
    print(m, ans)


for _ in range(int(input())):
    n = int(input())
    a = list(map(int, input().split()))
    l, h = 1000010000, -1
    for i in range(n):
        if a[i] >= 0:
            if (i and a[i - 1] < 0) or (i + 1 < n and a[i + 1] < 0):
                l = min(l, a[i])
                h = max(h, a[i])
    if l > h:
        print(0, 0)
    else:
        x = (l + h) // 2
        y = h - x
        for i in range(1, n):
            if a[i - 1] >= 0 and a[i] >= 0:
                y = max(y, abs(a[i] - a[i - 1]))
        print(y, x)


t = input()
t = int(t)
while t:
    t -= 1
    n = input()
    a = input()
    a = [int(str) for str in a.split()]
    #print('a = {}'.format(a))
    minn = 1e10
    dist = -1
    maxx = -1
    for i in range(len(a)):
        cur = a[i]
        if cur == -1:
            if i == 0:
                if a[i+1] != -1:
                    minn = min(a[i+1], minn)
                    maxx = max(a[i+1], maxx)
            elif i == len(a) - 1:
                if a[i-1] != -1:
                    minn = min(a[i-1], minn)
                    maxx = max(a[i-1], maxx)
            else:
                if a[i+1] != -1:
                    minn = min(a[i+1], minn)
                    maxx = max(a[i+1], maxx)
                if a[i-1] != -1:
                    minn = min(a[i-1], minn)
                    maxx = max(a[i-1], maxx)
        else:
            if i != 0 and a[i - 1] != -1:
                dist = max(dist, abs(a[i] - a[i-1]))
    if maxx == -1:
        maxx = minn = 0
    k = (maxx + minn) // 2
    dist = max(dist, abs(k - maxx))
    #print('dist = {}, k = {}, maxx = {}, minn = {}'.format(dist, k, maxx, minn))
    print(dist, k)


t = input()
t = int(t)
while t:
    t -= 1
    n = input()
    a = input()
    a = [int(str) for str in a.split()]
    #print('a = {}'.format(a))
    minn = 1e10
    dist = -1
    maxx = -1
    for i in range(len(a)):
        cur = a[i]
        if cur == -1:
            if i == 0 and a[i+1] != -1:
                minn = min(a[i+1], minn)
                maxx = max(a[i+1], maxx)
            elif i == len(a) - 1 and a[i-1] != -1:
                minn = min(a[i-1], minn)
                maxx = max(a[i-1], maxx)
            else:
                if a[i+1] != -1:
                    minn = min(a[i+1], minn)
                    maxx = max(a[i+1], maxx)
                if a[i-1] != -1:
                    minn = min(a[i-1], minn)
                    maxx = max(a[i-1], maxx)
        else:
            if i != 0 and a[i - 1] != -1:
                dist = max(dist, abs(a[i] - a[i-1]))
    k = (maxx + minn) // 2
    dist = max(dist, abs(k - minn))
    #print('dist = {}, k = {}, maxx = {}, minn = {}'.format(dist, k, maxx, minn))
    print(dist, k)


t=int(input())
for _ in range(t):
    n=int(input())
    a=list(map(int,input().split()))
    b=[]
    for i in range(n):
        b.append(a[i])
    s=set()
    for i in range(n):
        if a[i]==-1:
            if i>0 and i<n-1:
                if a[i-1]!=-1:
                    s.add(a[i-1])
                if a[i+1]!=-1:
                    s.add(a[i+1])
            elif i==0:
                if a[i+1]!=-1:
                    s.add(a[i+1])
            elif i==n-1:
                if a[i-1]!=-1:
                    s.add(a[i-1])
    if len(s)==0:
        k=0
        m=0
        for i in range(n):
            if a[i]==-1:
                a[i]=k
        for i in range(1,n):
            m=max(m,abs(a[i]-a[i-1]))
        print(m,k)
    else:
        k=sum(s)//len(s)
        m=0
        for i in range(n):
            if a[i]==-1:
                a[i]=k
        for i in range(1,n):
            m=max(m,abs(a[i]-a[i-1]))
        if sum(s)%len(s)!=0:
            m2=0
            k2=k+1
            for i in range(n):
                if b[i]==-1:
                    b[i]=k2
            for i in range(1,n):
                m2=max(m2,abs(b[i]-b[i-1]))
            if m2>m:
                print(m,k)
            else:
                print(m2,k2)
        else:
            print(m,k)


t=int(input())
for _ in range(t):
    n=int(input())
    a=list(map(int,input().split()))
    b=[]
    for i in range(n):
        b.append(a[i])
    s=set()
    for i in range(n):
        if a[i]==-1:
            if i>0 and i<n-1:
                if a[i-1]!=-1:
                    s.add(a[i-1])
                if a[i+1]!=-1:
                    s.add(a[i+1])
            elif i==0:
                if a[i+1]!=-1:
                    s.add(a[i+1])
            elif i==n-1:
                if a[i-1]!=-1:
                    s.add(a[i-1])
    if len(s)==0:
        k=0
        m=0
        for i in range(n):
            if a[i]==-1:
                a[i]=k
        for i in range(1,n):
            m=max(m,abs(a[i]-a[i-1]))
        print(m,k)
    else:
        k=(max(s)+min(s))//2
        m=0
        for i in range(n):
            if a[i]==-1:
                a[i]=k
        for i in range(1,n):
            m=max(m,abs(a[i]-a[i-1]))
        print(m,k)


# Template 1.0
import sys, re, math
from collections import deque, defaultdict, Counter, OrderedDict
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, radians, gcd
from heapq import heappush, heappop, heapify, nlargest, nsmallest
def STR(): return list(input())
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
def list2d(a, b, c): return [[c] * b for i in range(a)]
def sortListWithIndex(listOfTuples, idx):   return (sorted(listOfTuples, key=lambda x: x[idx]))
def sortDictWithVal(passedDic):
    temp = sorted(passedDic.items(), key=lambda kv: (kv[1], kv[0]))
    toret = {}
    for tup in temp:
        toret[tup[0]] = tup[1]
    return toret
def sortDictWithKey(passedDic):
    return dict(OrderedDict(sorted(passedDic.items())))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7

t = INT()

while(t!=0):
    n =INT()

    a = LIST()
    foo = set()
    mx = 0
    mn = INF
    for i in range(n):
        if(a[i]==-1):
            if(i==0):
                if(a[i+1]==-1):
                    continue
                else:
                    foo.add(a[i+1])
            elif(i==n-1):
                if(a[i-1]==-1):
                    continue
                else:
                    foo.add(a[i-1])
            else:
                if(a[i+1]!=-1):
                    foo.add(a[i+1])
                if(a[i-1]!=-1):
                    foo.add(a[i-1])

    if(len(foo)!=0):
        mx = max(foo)
        mn = min(foo)
        k = (mx+mn)//2
    else:
        k = 0

    overall = 0
    for j in range(n):
        if(a[j]==-1):
            a[j]=k
    # print(a)
    for j in range(1, n):
        overall = max(overall, abs(a[j]-a[j-1]))
    print(overall, k)

    t-=1


# Template 1.0
import sys, re, math
from collections import deque, defaultdict, Counter, OrderedDict
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, radians, gcd
from heapq import heappush, heappop, heapify, nlargest, nsmallest
def STR(): return list(input())
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
def list2d(a, b, c): return [[c] * b for i in range(a)]
def sortListWithIndex(listOfTuples, idx):   return (sorted(listOfTuples, key=lambda x: x[idx]))
def sortDictWithVal(passedDic):
    temp = sorted(passedDic.items(), key=lambda kv: (kv[1], kv[0]))
    toret = {}
    for tup in temp:
        toret[tup[0]] = tup[1]
    return toret
def sortDictWithKey(passedDic):
    return dict(OrderedDict(sorted(passedDic.items())))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7

t = INT()

while(t!=0):
    n =INT()

    a = LIST()
    foo = []
    mx = 0
    mn = INF
    for i in range(n-1):
        if(a[i]==-1):
            if(a[i+1]==-1):
                continue
            else:
                foo.append(a[i+1])
    if(a[0]!=-1):
        foo.append(a[0])
    foo.sort()

    if(len(foo)!=0):
        k = (foo[0]+foo[-1])//2
    else:
        k = 0

    overall = 0
    for j in range(n):
        if(a[j]==-1):
            a[j]=k
    # print(a)
    for j in range(1, n):
        overall = max(overall, abs(a[j]-a[j-1]))
    print(overall, k)

    t-=1


for _ in range(int(input())):
    n=int(input())
    lst=list(map(int,input().split()))
    if lst[0]!=-1 and lst[1]==-1:
        low=lst[0]
        high=lst[0]
    else:
        low=max(lst)
        high=0
    for i in range(1,n-1):
        if lst[i]!=-1 and (lst[i-1]==-1 or lst[i+1]==-1):
            if lst[i]<low:
                low=lst[i]
            if lst[i]>high:
                high=lst[i]
    if lst[n-1]!=-1 and lst[n-2]==-1:
        if lst[n-1]>high:
            high=lst[n-1]
        if lst[n-1]<low:
            low=lst[n-1]
    ans=int((low+high)/2)
    poss=high-ans
    for i in range(n-1):
        if lst[i]!=-1 and lst[i+1]!=-1:
            temp=abs(lst[i]-lst[i+1])
            if temp>poss:
                poss=temp
    print(poss,ans)


# -*- coding: utf-8 -*-
"""
Created on Sat Oct 24 01:28:09 2020

@author: Dark Soul
"""

for _ in range(int(input(''))):
    n=int(input(''))
    arr=list(map(int,input().split()))
    dorkar=[]
    if n==2:
        arr.sort()
        if arr[1]==-1:
            print(0,1)

        else:
            if arr[0]==-1:
                print(0,arr[1])
        continue
    for i in range(n):
        if arr[i]==-1:
            if i==0:
                if arr[i+1]!=-1:
                    dorkar.append(arr[i+1])
            elif i==n-1:
                if arr[i-1]!=-1:
                    dorkar.append(arr[i-1])
            else:
                if arr[i-1]!=-1:
                    dorkar.append(arr[i-1])
                if arr[i+1]!=-1:
                    dorkar.append(arr[i+1])
    dorkar.sort()
    if len(dorkar)==1:
        k=dorkar[0]
    else:
        k=(dorkar[0]+dorkar[len(dorkar)-1])//2
    for i in range(n):
        if arr[i]==-1:
            arr[i]=k
    m=0
    for i in range(n-1):
        m=max(m,abs(arr[i]-arr[i+1]))
    print(m,k)


# -*- coding: utf-8 -*-
"""
Created on Sat Oct 24 01:28:09 2020

@author: Dark Soul
"""

for _ in range(int(input(''))):
    n=int(input(''))
    arr=list(map(int,input().split()))
    dorkar=[]
    if n==2:
        arr.sort()
        if arr[1]==-1:
            print(0,1)

        else:
            if arr[0]==-1:
                print(0,arr[1])
        continue
    for i in range(n):
        if arr[i]==-1:
            if i==0:
                if arr[i+1]!=-1:
                    dorkar.append(arr[i+1])
            elif i==(n-1):
                if arr[i-1]!=-1:
                    dorkar.append(arr[i-1])
            else:
                if arr[i-1]!=-1:
                    dorkar.append(arr[i-1])
                if arr[i+1]!=-1:
                    dorkar.append(arr[i+1])
    dorkar.sort()
    if len(dorkar)==1:
        k=dorkar[0]
    else:
        k=(dorkar[0]+dorkar[len(dorkar)-1])//2
    for i in range(n):
        if arr[i]==-1:
            arr[i]=k
    m=0
    for i in range(n-1):
        m=max(m,abs(arr[i]-arr[i+1]))
    print(m,k)


# -*- coding: utf-8 -*-
"""
Created on Sat Oct 24 01:28:09 2020

@author: Dark Soul
"""

for _ in range(int(input(''))):
    n=int(input(''))
    arr=list(map(int,input().split()))
    dorkar=[]
    if n==2:
        arr.sort()
        if arr[1]==-1:
            print(0,1)

        else:
            if arr[0]==-1:
                print(0,arr[1])
        continue
    for i in range(n):
        if arr[i]!=-1:
            if i==0:
                if arr[i+1]==-1:
                    dorkar.append(arr[i])
            elif i==(n-1):
                if arr[i-1]==-1:
                    dorkar.append(arr[i])
            else:
                if arr[i-1]==-1 or arr[i+1]==-1:
                    dorkar.append(arr[i])
    dorkar.sort()
    if len(dorkar)==1:
        k=dorkar[0]
    else:
        k=(dorkar[0]+dorkar[len(dorkar)-1])//2
    for i in range(n):
        if arr[i]==-1:
            arr[i]=k
    m=0
    for i in range(n-1):
        m=max(m,abs(arr[i]-arr[i+1]))
    print(m,k)


# -*- coding: utf-8 -*-
"""
Created on Sat Oct 24 01:28:09 2020

@author: Dark Soul
"""

for _ in range(int(input(''))):
    n=int(input(''))
    arr=list(map(int,input().split()))
    dorkar=[]
    if n==2:
        arr.sort()
        if arr[1]==-1:
            print(0,1)

        else:
            if arr[0]==-1:
                print(0,arr[1])
        continue
    for i in range(n):
        if arr[i]!=-1:
            if i==0:
                if arr[i+1]==-1:
                    dorkar.append(arr[i])
            elif i==(n-1):
                if arr[i-1]==-1:
                    dorkar.append(arr[i])
            else:
                if arr[i-1]==-1 or arr[i+1]==-1:
                    dorkar.append(arr[i])
    if len(dorkar)==0:
        print(0,0)
        continue
    k=(min(dorkar)+max(dorkar))//2
    for i in range(n):
        if arr[i]==-1:
            arr[i]=k
    m=0
    for i in range(n-1):
        m=max(m,abs(arr[i]-arr[i+1]))
    print(m,k)


# -*- coding: utf-8 -*-
"""
Created on Sat Oct 24 01:28:09 2020

@author: Dark Soul
"""

for _ in range(int(input(''))):
    n=int(input(''))
    arr=list(map(int,input().split()))
    dorkar=[]
    if n==2:
        arr.sort()
        if arr[1]==-1:
            print(0,1)

        else:
            if arr[0]==-1:
                print(0,arr[1])
        continue
    for i in range(n):
        if arr[i]==-1:
            if i==0:
                if arr[i+1]!=-1:
                    dorkar.append(arr[i+1])
            elif i==n-1:
                if arr[i-1]!=-1:
                    dorkar.append(arr[i-1])
            else:
                if arr[i-1]!=-1:
                    dorkar.append(arr[i-1])
                if arr[i+1]!=-1:
                    dorkar.append(arr[i+1])
    dorkar.sort()
    k=(dorkar[0]+dorkar[len(dorkar)-1])//2
    for i in range(n):
        if arr[i]==-1:
            arr[i]=k
    m=0
    for i in range(n-1):
        m=max(m,abs(arr[i]-arr[i+1]))
    print(m,k)


import math
t=int(input())
for i in range(t):
    n=int(input())
    l=[]
    li=list(map(int,input().split()))
    for k in range(n):
        if(li[k]==-1):
            if(k-1>=0):
                if(li[k-1]!=-1):
                    l.append(li[k-1])
            if(k+1<n):
                if(li[k+1]!=-1):
                    l.append(li[k+1])
    if(l==[]):
        ans=0
    else:
        a=max(l)
        b=min(l)
        ans=(a+b)//2
    for k in range(n):
        if(li[k]==-1):
            li[k]=ans
    maxi=0
    for k in range(1,n):
        if(abs(li[k]-li[k-1])>maxi):
            maxi=abs(li[k]-li[k-1])
    print(maxi,end=" ")
    print(ans)


import math
t=int(input())
for i in range(t):
    n=int(input())
    l=[]
    li=list(map(int,input().split()))
    for k in range(n):
        if(li[k]==-1):
            if(k-1>=0):
                if(li[k-1]!=-1):
                    l.append(li[k-1])
            if(k+1<n):
                if(li[k+1]!=-1):
                    l.append(li[k+1])
    if(l==[]):
        ans=0
    else:
        a=max(l)
        b=min(l)
    ans=(a+b)//2
    for k in range(n):
        if(li[k]==-1):
            li[k]=ans
    maxi=0
    for k in range(1,n):
        if(abs(li[k]-li[k-1])>maxi):
            maxi=abs(li[k]-li[k-1])
    print(maxi,end=" ")
    print(ans)


import math
t=int(input())
for i in range(t):
    n=int(input())
    li=list(map(int,input().split()))

    maxi=0
    mini=1000000000
    h=-2
    maxdiff=0
    for j in li:
        if(j!=-1):
            if(j<mini):
                mini=j
            if(maxi<j):
                maxi=j

    for k in range(len(li)):
        if(li[k]==-1):
            li[k]=(maxi+mini)//2
    for k in range(1,len(li)):
        if(abs(li[k]-li[k-1])>maxdiff):
            maxdiff=abs(li[k]-li[k-1])
    print(maxdiff ,end=" ")
    print((maxi+mini)//2 )


t=int(input())
for _ in range(t):
    n=int(input())
    a=list(map(int,input().split()))
    b=[]
    c=[]
    for i in range(1,n-1):
        if a[i]==-1 and a[i+1]==-1:
            f=1
        if a[i]==-1 and a[i-1]==-1:
            f=1
        elif a[i]!=-1 and a[i+1]!=-1:
            b.append(abs(a[i+1]-a[i]))
        elif a[i]==-1:
            c.append(a[i+1])
            c.append(a[i-1])
    if a[-1]==-1 and a[-2]!=-1:
        c.append(a[-2])
    if a[0]==-1 and a[1]!=-1:
        c.append(a[1])
    if len(c)==0:
        print(0,1)
        continue
    else:
        d=(max(c)+min(c))//2
    e=0
    if len(b)>0:
        e=max(b)
    print(max(e,abs(max(c)-d),abs(min(c)-d)),d)


t=int(input())
for _ in range(t):
    n=int(input())
    a=list(map(int,input().split()))
    c=[]
    for i in range(1,n-1):
        if a[i]==-1:
            if a[i-1]!=-1:
                c.append(a[i-1])
            if a[i+1]!=-1:
                c.append(a[i+1])
    if a[-1]==-1 and a[-2]!=-1:
        c.append(a[-2])
    if a[0]==-1 and a[1]!=-1:
        c.append(a[1])
    if len(c)==0:
        print(0,1)
        continue
    else:
        d=(max(c)+min(c))//2
    b=[]
    for i in range(n):
        if a[i]==-1:
            a[i]=d
    for i in range(n-1):
        b.append(abs(a[i+1]-a[i]))
    print(max(b),d)


t = int(input())
for i in range(t):
    n = int(input())
    a = list(map(int,input().split()))
    b=[x for x in a if x != -1]
    if(len(b)==0):
        res2=0
    else:
        res2 = int((max(b)+min(b))/2)
    a = [res2 if x ==-1 else x for x in a]
    diff=0
    for i in range(len(a)-1):
        if abs(a[i]-a[i+1])>diff:
            diff=abs(a[i]-a[i+1])
    print(diff,end=" ")
    print(res2)


t = int(input())
for i in range(t):
    n = int(input())
    a = list(map(int,input().split()))
    minimo = 100000000000
    maximo = 0
    for i in range(len(a)):
        if (i>0 and a[i]==-1 and a[i-1] != -1):
            minimo=min(minimo,a[i-1])
            maximo=max(maximo,a[i-1])
        if (i<len(a)-1 and a[i]==-1 and a[i+1] != -1):
            minimo=min(minimo,a[i+1])
            maximo=max(maximo,a[i+1])

    if minimo==1000000 and maximo == 0:
        res2=0
    else:
        res2=int((minimo+maximo)/2)
    a=[res2 if x==-1 else x for x in a]
    diff=0
    for i in range(len(a)-1):
        if abs(a[i]-a[i+1])>diff:
            diff=abs(a[i]-a[i+1])
    print(diff,end=" ")
    print(res2)


t = int(input())
for i in range(t):
    n = int(input())
    a = list(map(int,input().split()))
    minimo = 1000000
    maximo = 0
    for i in range(len(a)):
        if (i>0 and a[i]==-1 and a[i-1] != -1):
            minimo=min(minimo,a[i-1])
            maximo=max(maximo,a[i-1])
        if (i<len(a)-1 and a[i]==-1 and a[i+1] != -1):
            minimo=min(minimo,a[i+1])
            maximo=max(maximo,a[i+1])

    if minimo==1000000 and maximo == 0:
        res2=0
    else:
        res2=int((minimo+maximo)/2)
    a=[res2 if x==-1 else x for x in a]
    diff=0
    for i in range(len(a)-1):
        if abs(a[i]-a[i+1])>diff:
            diff=abs(a[i]-a[i+1])
    print(diff,end=" ")
    print(res2)


t = int(input())
for i in range(t):
    n = int(input())
    a = list(map(int,input().split()))
    minimo = 100000000000
    maximo = 0
    for i in range(len(a)):
        if (i>0 and a[i]==-1 and a[i-1] != -1):
            minimo=min(minimo,a[i-1])
            maximo=max(maximo,a[i-1])
        if (i<len(a)-1 and a[i]==-1 and a[i+1] != -1):
            minimo=min(minimo,a[i+1])
            maximo=max(maximo,a[i+1])

    if minimo==100000000000 and maximo == 0:
        res2=0
    else:
        res2=int((minimo+maximo)/2)
    a=[res2 if x==-1 else x for x in a]
    diff=0
    for i in range(len(a)-1):
        if abs(a[i]-a[i+1])>diff:
            diff=abs(a[i]-a[i+1])
    print(diff,end=" ")
    print(res2)


import sys
sys.stdin = open('input.txt', 'r')
sys.stdout = open('output.txt', 'w')

for _ in range(int(input())):
    n=int(input())
    L=list(map(int,input().split()))
    R=[]
    for i in range(n):
        if L[i]==-1:
            if i>0 and L[i-1]!=-1:
                R.append(L[i-1])
            if i<n-1 and L[i+1]!=-1:
                R.append(L[i+1])
    R.sort()
    if len(R)!=0:
        ans=(R[0]+R[-1])//2
    else:
        ans=0
    for i in range(n):
        if L[i]==-1: L[i]=ans
    V=abs(L[0]-L[1])
    for i in range(n-1):
        r=abs(L[i]-L[i+1])
        if V<r: V=r
    print(V,ans)


# import sys
# sys.stdin = open('input.txt', 'r')
# sys.stdout = open('output.txt', 'w')

ans = []

def maxAbsDiff(arr, n):
    maxd = 0
    for i in range(n-1):
        dif = abs(arr[i] - arr[i+1])
        if(dif>maxd):
            maxd = dif
    return maxd

for _ in range(int(input())):
    s = int(input())
    a = [int(i) for i in input().split()]
    sump  = 0
    lenp = 0

    try:
        for i in a:
            if(i>0):
                sump+=i
                lenp+=1
        ave = sump//lenp
        an = [ave if x==-1 else x for x in a]
        dif = maxAbsDiff(an,len(an))

    except:
        ave = 0
        dif = 0

    ans.append([dif,ave])

for i in ans:
    print(*i)


import sys
sys.stdin = open('input.txt', 'r')
sys.stdout = open('output.txt', 'w')

ans = []

def maxAbsDiff(arr, n):
    maxd = 0
    for i in range(n-1):
        dif = abs(arr[i] - arr[i+1])
        if(dif>maxd):
            maxd = dif
    return maxd

for _ in range(int(input())):
    s = int(input())
    a = [int(i) for i in input().split()]
    sump  = 0
    lenp = 0

    try:
        for i in a:
            if(i>0):
                sump+=i
                lenp+=1
        ave = sump//lenp
        an = [ave if x==-1 else x for x in a]
        dif = maxAbsDiff(an,len(an))

    except:
        ave = 0
        dif = 0

    ans.append([dif,ave])

print(*ans)


n = int(input())
c = []
ans = []
flag = 0

def swap(a,b,i):
	a1 = [j for j in a]
	b1 = [j for j in b]
	a1[i],b1[i] = b1[i],a1[i]
	a = ''.join(a1)
	b = ''.join(b1)
	return (a,b)

for i in range(n):
	s1 = input()
	s2 = input()
	s3 = input()

	if(len(set([s1[0],s2[0],s3[0]]))==3):
		ans.append('NO')
		continue

	for i in range(len(s1)):
		if(len(set([s1[i],s2[i],s3[i]]))==3):

			ans.append('NO')
			flag = 1
			break

		if(s1[i] == s3[i] and not s2[i] == s3[i]):
			s2,s3=swap(s2,s3,i)
		elif(s2[i] == s3[i] and not s1[i] == s3[i]):
			s1,s3=swap(s1,s3,i)
		elif(s1[i]==s2[i] and s1[i]==s3[i]):
			continue
		else:
			ans.append('NO')
			flag = 1
			break
	if(s1==s2 and not flag):
		ans.append('YES')
	elif(not flag):
		ans.append('NO')
for i in ans:
	print(i)


# import sys
# sys.stdin = open('input.txt', 'r')
# sys.stdout = open('output.txt', 'w')

for _ in range(int(input())):
    n=int(input())
    L=list(map(int,input().split()))
    R=[]
    for i in range(n):
        if L[i]==-1:
            if i>0 and L[i-1]!=-1:
                R.append(L[i-1])
            if i<n-1 and L[i+1]!=-1:
                R.append(L[i+1])
    R.sort()
    if len(R)!=0:
        ans=(R[0]+R[-1])//2
    else:
        ans=0
    for i in range(n):
        if L[i]==-1: L[i]=ans
    V=abs(L[0]-L[1])
    for i in range(n-1):
        r=abs(L[i]-L[i+1])
        if V<r: V=r
    print(V,ans)


for _ in range(int(input())):
    n=int(input())
    list1=[*map(int,input().split())]
    maxi=0
    if(list1.count(-1)==n):
        print(0,1)
    else:
        s = (max(list1) + min(i for i in list1 if i != -1)) // 2

        for i in range(len(list1)):
            if (list1[i ]== -1):
                list1[i]=s

        for i in range(n - 1):
            if (abs(list1[i] - list1[i + 1]) >= maxi):
                maxi = abs(list1[i] - list1[i + 1])
        print(maxi, s)


for _ in range(int(input())):
    n=int(input())
    list1=[*map(int,input().split())]
    maxi=0
    mini=10**9+1
    maxim=-mini
    if(list1.count(-1)==n):
        print(0,1)
    else:
        for i in range(n-1):
            if(list1[i]!=-1 and (list1[i-1]==-1 or list1[i+1]==-1)):
                mini=min(mini,list1[i])
                maxim=max(maxim,list1[i])

        s=(mini+maxim)//2
        for i in range(len(list1)):
            if (list1[i ]== -1):
                list1[i]=s

        for i in range(n - 1):
            if (abs(list1[i] - list1[i + 1]) >= maxi):
                maxi = abs(list1[i] - list1[i + 1])
        print(maxi, s)


for _ in range(int(input())):
    n=int(input())
    list1=[*map(int,input().split())]
    list2=[]
    for i in range(len(list1)):
            if(i>0 and list1[i+1]==-1 and list1[i]!=-1):
                list2.append(i)
            if(i<n-1 and list1[i+1]==-1 and list1[i]!=-1):
                list2.append(i)
    if(len(list2)==0):
            s=0
    else:
            s=(max(list2)+min(list2))//2
    for i in range(len(list1)):
            if (list1[i ]== -1):
                list1[i]=s
    maxi=abs(list1[0]-list1[1])
    for i in range(n - 1):
                maxi = max(maxi,abs(list1[i] - list1[i + 1]))
    print(maxi, s)


for _ in range(int(input())):
    n=int(input())
    list1=[*map(int,input().split())]
    list2=[]
    for i in list1:
            if(i!=-1):
                list2.append(i)
    if(len(list2)==0):
            s=0
    else:
            list2.sort()
            s=(list2[0]+list2[-1])//2
    for i in range(len(list1)):
            if (list1[i ]== -1):
                list1[i]=s
    maxi=abs(list1[0]-list1[1])
    for i in range(n - 1):
            if (abs(list1[i] - list1[i + 1]) >= maxi):
                maxi = abs(list1[i] - list1[i + 1])
    print(maxi, s)


for _ in range(int(input())):
    n=int(input())
    list1=[*map(int,input().split())]
    max=0
    if(list1.count(-1)==n):
        print(0,1)
    else:
        s=(max(s)+min(i for i in list1 if i!=-1))//2

        for i in range(n - 1):
            if (abs(list1[i] - list1[i + 1]) >= max):
                max = abs(list1[i] - list1[i + 1])
        print(max, s)


for _ in range(int(input())):
    n=int(input())
    list1=[*map(int,input().split())]
    maxi=0
    if(list1.count(-1)==n):
        print(0,1)
    else:
        s=(min(i for i in list1 if i!=-1)+max(i for i in list1 if i!=-1))//2
        for i in range(len(list1)):
            if (list1[i ]== -1):
                list1[i]=s

        for i in range(n - 1):
            if (abs(list1[i] - list1[i + 1]) >= maxi):
                maxi = abs(list1[i] - list1[i + 1])
        print(maxi, s)


for _ in range(int(input())):
    n=int(input())
    list1=[*map(int,input().split())]
    list2=[]
    maxi=0
    for i in range(len(list1)):
        if(list1[i]==-1):
            if(i>0 and list1[i-1]!=-1 ):
                list2.append(list1[i-1])
            if(i<n-1 and list1[i+1]!=-1):
                list2.append(list1[i+1])
    if(len(list2)==0):
            s=0
    else:
            s=(max(list2)+min(list2))//2
    for i in range(len(list1)):
            if (list1[i ]== -1):
                  list1[i]=s
    for i in range(n - 1):
                maxi = max(maxi,abs(list1[i] - list1[i + 1]))
    print(maxi, s)


for _ in range(int(input())):
    n=int(input())
    list1=[*map(int,input().split())]
    maxi=0
    mini=10**9+1
    maxim=-mini
    if(list1.count(-1)==n):
        print(0,1)
    else:
        for i in range(1,n-1):
            if(list1[i]!=-1 and (list1[i-1]==-1 or list1[i+1]==-1)):
                mini=min(mini,list1[i])
                maxim=max(maxim,list1[i])

        s=(mini+maxim)//2
        for i in range(len(list1)):
            if (list1[i ]== -1):
                list1[i]=s

        for i in range(n - 1):
            if (abs(list1[i] - list1[i + 1]) >= maxi):
                maxi = abs(list1[i] - list1[i + 1])
        print(maxi, s)


for _ in range(int(input())):
    n=int(input())
    list1=[*map(int,input().split())]
    list2=[]
    maxi=0
    for i in range(len(list1)):
        if(list1[i]==-1):
            if(i>0 and list1[i-1]!=-1 ):
                list2.append(list1[i-1])
            if(i<n-1 and list1[i+1]==-1):
                list2.append(list1[i+1])
    if(len(list2)==0):
            s=0
    else:
            s=(max(list2)+min(list2))//2
    for i in range(len(list1)):
            if (list1[i ]== -1):
                  list1[i]=s
    for i in range(n - 1):
                maxi = max(maxi,abs(list1[i] - list1[i + 1]))
    print(maxi, s)


for _ in range(int(input())):
    n=int(input())
    list1=[*map(int,input().split())]
    maxi=0
    mini=10**9+1
    maxim=0
    if(list1.count(-1)==n):
        print(0,1)
    else:
        for i in range(len(list1)-1):
            if(list1[i]!=-1 and (list1[i-1]==-1 or list1[i+1]==-1)):
                mini=min(mini,list1[i])
                maxim=max(maxim,list1[i])

        s=(mini+maxim)//2
        for i in range(len(list1)):
            if (list1[i ]== -1):
                list1[i]=s

        for i in range(n - 1):
            if (abs(list1[i] - list1[i + 1]) >= maxi):
                maxi = abs(list1[i] - list1[i + 1])
        print(maxi, s)


for _ in range(int(input())):
    n=int(input())
    list1=[*map(int,input().split())]
    list2=[]
    if(list1.count(-1)==n):
        print(0,1)
    else:
        for i in list1:
            if(i!=-1):
                list2.append(i)
        if(len(list2)==0):
            s=0
        else:
            list2.sort()
            s=(list2[0]+list2[-1])//2
        for i in range(len(list1)):
            if (list1[i ]== -1):
                list1[i]=s
        maxi=abs(list1[0]-list1[1])
        for i in range(n - 1):
            if (abs(list1[i] - list1[i + 1]) >= maxi):
                maxi = abs(list1[i] - list1[i + 1])
        print(maxi, s)


for _ in range(int(input())):
    n=int(input())
    list1=[*map(int,input().split())]
    max=0
    if(list1.count(-1)==n):
        print(0,1)
    else:
        s = sum(i for i in list1 if i != -1)
        count = len([i for i in list1 if i != -1])
        s //= count
        for i in range(len(list1)):
            if (list1[i ]== -1):
                list1[i]=s

        for i in range(n - 1):
            if (abs(list1[i] - list1[i + 1]) >= max):
                max = abs(list1[i] - list1[i + 1])
        print(max, s)


for _ in range(int(input())):
    n=int(input())
    list1=[*map(int,input().split())]
    maxi=0
    mini=10**9+1
    maxim=0
    if(list1.count(-1)==n):
        print(0,1)
    else:
        for i in range(1,len(list1)-1):
            if(list1[i]!=-1 and (list1[i-1]==-1 or list1[i+1]==-1)):
                mini=min(mini,list1[i])
                maxim=max(maxim,list1[i])
        s=(mini+maxim)//2
        for i in range(len(list1)):
            if (list1[i ]== -1):
                list1[i]=s

        for i in range(n - 1):
            if (abs(list1[i] - list1[i + 1]) >= maxi):
                maxi = abs(list1[i] - list1[i + 1])
        print(maxi, s)


for _ in range(int(input())):
    n=int(input())
    list1=[*map(int,input().split())]
    if(list1.count(-1)==n):
        print(0,1)
    else:
        s=(min(i for i in list1 if i!=-1)+max(i for i in list1 if i!=-1))//2
        for i in range(len(list1)):
            if (list1[i ]== -1):
                list1[i]=s
        maxi=abs(list1[0]-list1[1])
        for i in range(n - 1):
            if (abs(list1[i] - list1[i + 1]) >= maxi):
                maxi = abs(list1[i] - list1[i + 1])
        print(maxi, s)


n = int(input())
for _ in range(n):
    input()
    nums = list(map(int,input().split()))
    if len(set(nums)) == 1 and nums[0]==-1:
        print(0,end=' ')
        print(1,end='')
        break
    minn, maxx, get = float('inf'), float('-inf'),float('-inf')
    for i in range(len(nums)):
        if nums[i] == -1:
            if i == 0 and nums[i+1] != -1:
                minn = min(minn,nums[i+1])
                maxx = max(maxx,nums[i+1])
            elif i == 0: continue
            elif i == len(nums)-1 and nums[i-1] != -1:
                minn = min(minn,nums[i-1])
                maxx = max(maxx,nums[i-1])
            elif i==len(nums)-1:continue
            elif nums[i+1]!=-1 and nums[i-1]!= -1:
                minn = min(minn,nums[i+1],nums[i-1])
                maxx = max(maxx,nums[i+1],nums[i-1])
            elif nums[i-1] != -1:
                minn = min(minn, nums[i - 1])
                maxx = max(maxx, nums[i - 1])
            elif nums[i+1] != -1:
                minn = min(minn, nums[i + 1])
                maxx = max(maxx, nums[i + 1])

        elif i !=len(nums)-1 and nums[i+1] != -1:
            get = max(get,abs(nums[i]-nums[i+1]))
    print(max(get,(maxx-minn)//2),end=' ')
    print((maxx+minn)//2)


n = int(input())
for _ in range(n):
    input()
    nums = list(map(int,input().split()))
    minn, maxx = 10000000,0
    for i in range(len(nums)):
        if i == 0:
           if nums[i] != -1 and nums[i+1] == -1:
               minn = min(minn,nums[i])
               maxx = max(maxx,nums[i])
        elif i==len(nums)-1:
            if nums[i]!=-1 and nums[i-1] == -1:
                minn = min(minn,nums[i])
                maxx = max(maxx,nums[i])
        elif nums[i] != -1 and (nums[i+1] == -1 or nums[i-1] == -1):
            minn = min(minn,nums[i])
            maxx = max(maxx,nums[i])
    if minn == 10000000:
        print(0, end=' ')
        print(1)
        continue
    rep = (minn+maxx)//2
    res = 0
    for i in range(len(nums)):
        if i == len(nums)-1:
            break
        elif nums[i] == -1:
            if nums[i+1] != -1:
                res = max(res,abs(rep-nums[i+1]))
        else:
            if nums[i+1] == -1:
                res = max(res,abs(rep-nums[i]))
            else:
                res = max(res,abs(nums[i]-nums[i+1]))
    print(res,end=' ')
    print(rep)


n = int(input())
for _ in range(n):
    input()
    nums = list(map(int,input().split()))
    minn, maxx = 10000000,0
    for i in range(len(nums)):
        if i == 0:
           if nums[i] != -1 and nums[i+1] == -1:
               minn = min(minn,nums[i])
               maxx = max(maxx,nums[i])
        elif i==len(nums)-1:
            if nums[i]!=-1 and nums[i-1] == -1:
                minn = min(minn,nums[i])
                maxx = max(maxx,nums[i])
        elif nums[i] != -1 and (nums[i+1] == -1 or nums[i-1] == -1):
            minn = min(minn,nums[i])
            maxx = max(maxx,nums[i])
    if minn == 10000000:
        print(0, end=' ')
        print(1)
        continue
    rep = (minn+maxx)//2
    res = 0
    for i in range(len(nums)):
        if nums[i] == -1:
            nums[i] = rep
        if i:
            res = max(res,abs(nums[i]-nums[i-1]))

    print(res,end=' ')
    print(rep)


n = int(input())
for _ in range(n):
    input()
    nums = list(map(int,input().split()))
    minn, maxx = 10000000000,0
    for i in range(len(nums)):
        if i == 0:
           if nums[i] != -1 and nums[i+1] == -1:
               minn = min(minn,nums[i])
               maxx = max(maxx,nums[i])
        elif i==len(nums)-1:
            if nums[i]!=-1 and nums[i-1] == -1:
                minn = min(minn,nums[i])
                maxx = max(maxx,nums[i])
        elif nums[i] != -1 and (nums[i+1] == -1 or nums[i-1] == -1):
            minn = min(minn,nums[i])
            maxx = max(maxx,nums[i])
    if minn == 10000000000:
        print(0, end=' ')
        print(1)
        continue
    rep = (minn+maxx)//2
    res = 0
    for i in range(len(nums)):
        if nums[i] == -1:
            nums[i] = rep
        if i:
            res = max(res,abs(nums[i]-nums[i-1]))

    print(res,end=' ')
    print(rep)


n = int(input())
for _ in range(n):
    input()
    nums = list(map(int,input().split()))
    if len(set(nums)) == 1 and nums[0]==-1:
        print(0,end=' ')
        print(1)
        continue
    minn, maxx, get = float('inf'), float('-inf'),float('-inf')
    for i in range(len(nums)):
        if nums[i] == -1:
            if i == 0 and nums[i+1] != -1:
                minn = min(minn,nums[i+1])
                maxx = max(maxx,nums[i+1])
            elif i == 0: continue
            elif i == len(nums)-1 and nums[i-1] != -1:
                minn = min(minn,nums[i-1])
                maxx = max(maxx,nums[i-1])
            elif i==len(nums)-1:continue
            elif nums[i+1]!=-1 and nums[i-1]!= -1:
                minn = min(minn,nums[i+1],nums[i-1])
                maxx = max(maxx,nums[i+1],nums[i-1])
            elif nums[i-1] != -1:
                minn = min(minn, nums[i - 1])
                maxx = max(maxx, nums[i - 1])
            elif nums[i+1] != -1:
                minn = min(minn, nums[i + 1])
                maxx = max(maxx, nums[i + 1])

        elif i !=len(nums)-1 and nums[i+1] != -1:
            get = max(get,abs(nums[i]-nums[i+1]))
    print(max(get,(maxx-minn)//2),end=' ')
    print((maxx+minn)//2)


def program():
    n=int(input())
    l=list(map(int, input().split()))
    l2=[]
    l3=[]
    for i in range(n):
        if l[i]==-1:
            if i==0:
                nex=l[1]
                prev=-1
            elif i==n-1:
                nex=-1
                prev=l[n-2]
            else:
                nex=l[i+1]
                prev=l[i-1]

            if nex!=-1 :
                l2.append(nex)
            if prev!=-1:
                l2.append(prev)

        else:
            if i==0:
                nex=l[1]
                prev=-1
            elif i==n-1:
                nex=-1
                prev=l[n-2]
            else:
                nex=l[i+1]
                prev=l[i-1]

            if nex!=-1:
                l3.append(abs(l[i]-nex))
            if prev!=-1:
                l3.append(abs(l[i]-prev))

    if len(l2)==0:
        print("0 0")
        return 0

    l2=set(l2)

    k=(max(l2)+min(l2))//2
    if len(l3)==0:
        m=max(l2)-k
    else:
        m=max(max(l3),max(l2)-k)

    print(m,k)

t=int(input())
for i in range(t):
    program()


def program():
    n=int(input())
    l=list(map(int, input().split()))
    l2=[]
    l3=[]
    for i in range(n):
        if l[i]==-1:
            if i==0:
                nex=l[1]
                prev=-1
            elif i==n-1:
                nex=-1
                prev=l[n-2]
            else:
                nex=l[i+1]
                prev=l[i-1]

            if nex!=-1 and nex not in l2:
                l2.append(nex)
            if prev!=-1 and prev not in l2:
                l2.append(prev)

        else:
            if i==0:
                nex=l[1]
                prev=-1
            elif i==n-1:
                nex=-1
                prev=l[n-2]
            else:
                nex=l[i+1]
                prev=l[i-1]

            if nex!=-1:
                l3.append(abs(l[i]-nex))
            if prev!=-1:
                l3.append(abs(l[i]-prev))

    if len(l2)==0:
        print("0 0")
        return 0

    k=(max(l2)+min(l2))//2
    if len(l3)==0:
        m=max(l2)-k
    else:
        m=max(max(l3),max(l2)-k)

    print(m,k)

t=int(input())
for i in range(t):
    program()


def program():
    n=int(input())
    l=list(map(int, input().split()))
    l2=[]
    for i in range(n):
        if l[i]==-1:
            if i==0:
                nex=l[1]
                prev=-1
            elif i==n-1:
                nex=-1
                prev=l[n-2]
            else:
                nex=l[i+1]
                prev=l[i-1]

            if nex!=-1 and nex not in l2:
                l2.append(nex)
            if prev!=-1 and prev not in l2:
                l2.append(prev)

    if len(l2)==0:
        print("0 0")
        return 0

    k=(max(l2)+min(l2))//2

    for i in range(n):
        if l[i]==-1:
            l[i]=k

    m=abs(l[0]-l[1])

    for i in range(1,n-1):
        if abs(l[i]-l[i+1])>m:
            m=abs(l[i]-l[i+1])

    print(m,k)

t=int(input())
for i in range(t):
    program()


def program():
    n=int(input())
    l=list(map(int, input().split()))
    l2=[]
    for i in range(n):
        if l[i]==-1:
            if i==0:
                nex=l[1]
                prev=-1
            elif i==n-1:
                nex=-1
                prev=l[n-2]
            else:
                nex=l[i+1]
                prev=l[i-1]

            if nex!=-1 and nex not in l2:
                l2.append(nex)
            if prev!=-1 and prev not in l2:
                l2.append(prev)

    if len(l2)==0:
        print("0 0")
        return 0

    k=(max(l2)+min(l2))//2

    for i in range(n):
        if l[i]==-1:
            l[i]=k

    l3=[]
    for i in range(n-1):
        l3.append(abs(l[i]-l[i+1]))

    print(max(l3),k)

t=int(input())
for i in range(t):
    program()


for _ in range(int(input())):
    n=int(input())
    a=list(map(int,input().split()))
    b=[]
    for i in range(n):
        if a[i]==-1:
            if i>0 and a[i-1]!=-1: b.append(a[i-1])
            if i<n-1 and a[i+1]!=-1: b.append(a[i+1])
    if len(b)==0:
        z=0
    else:
        z=(max(b)+min(b))//2
    for i in range(n):
        if a[i]==-1:
            a[i]=z
    k=abs(a[0]-a[1])
    for i in range(n-1):
        if abs(a[i]-a[i+1])>k:k=abs(a[i]-a[i+1])
    print(k,z)


t=int(input())
for i in range(t):
	n=int(input())
	l=list(map(int,input().split()))
	mn = 10**9+1
	mx = -2
	ans = 0
	for i in range(n):
		if(l[i]==-1):
			if(i-1>=0 and l[i-1]!=-1):
				mx=max(mx,l[i-1])
				mn=min(mn,l[i-1])
			if(i+1<n and l[i+1]!=-1):
				mn=min(mn,l[i+1])
				mx=max(mx,l[i+1])
		else:
			if(i-1>=0 and l[i-1]!=-1):
				ans=max(ans,abs(l[i]-l[i-1]))
			if(i+1<n and l[i+1]!=-1):
				ans=max(ans,abs(l[i]-l[i+1]))
	# print("mx",mx)
	# print("mn",mn)
	v=0
	if(mn!=10**9+1):
		v = mx-mn
		if(v%2!=0):
			z=v//2+1
		else:
			z=v//2
		v = mx-z
		ans=max(ans,z)
	print(ans,v)


t=int(input())
for _ in range(t):
    n=int(input())
    a=list(map(int,input().split()))
    if a.count(-1)==len(a):
        print(0,1)
    else:
        d={}

        for i in range(n):
            if i+1 < n and a[i]==-1 and a[i+1]!=-1:
                d[a[i+1]]=1
            if i-1 >=0 and a[i]==-1 and a[i-1]!=-1:
                d[a[i-1]]=1
        m=0
        for  i in range(n-1):
            if a[i]!=-1 and a[i+1]!=-1:
                m=max(m,abs(a[i]-a[i+1]))

        s=0
        for i in d:
            s+=i
        if s%len(d)==0:
            k=s//len(d)
            for  i in range(n):
                if a[i]==-1:
                    a[i]=k
            for i in range(1,n):
                m=max(m,abs(a[i]-a[i-1]))
            print(m,k)
        else:
            t1=s//len(d)
            t2=t1+1
            v=a.copy()
            for  i in range(n):
                if a[i]==-1:
                    a[i]=t1
                if v[i]==-1:
                    v[i]=t2
            q=m
            for i in range(1,n):
                m=max(m,abs(a[i]-a[i-1]))
                q=max(q,abs(v[i]-v[i-1]))
            if m<q:
                print(m,t1)
            else:
                print(q,t2)