#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <algorithm>
#include <cassert>
#include <ctime>
#include <random>

using namespace std;

const int INF = 1e9;

int a[1000000 + 5];

vector < pair < int, int > > ans;


const int array_size = 1e5 + 5;
int t[array_size * 4], lazy[array_size * 4];

void push(int v, int tl, int tr)
{
    t[v] += lazy[v] * (tr - tl + 1);
    if(tl != tr)
    {
        lazy[v << 1] += lazy[v];
        lazy[(v << 1) + 1] += lazy[v];
    }
    lazy[v] = 0;
    return;
}

void build(int v, int tl, int tr)
{
    if(tl == tr)
    {
        t[v] = a[tl];
        return;
    }
    int tm = (tl + tr) >> 1;
    build(v << 1, tl, tm);
    build((v << 1) + 1, tm + 1, tr);
    t[v] = t[v << 1] + t[(v << 1) + 1];
    return;
}

void update(int v, int tl, int tr, int l, int r, int add)
{
    if(l > r)
        return;
    if(l == tl && r == tr)
    {
        lazy[v] += add;
        push(v, tl, tr);
        return;
    }
    push(v, tl, tr);
    int tm = (tl + tr) >> 1;
    update(v << 1, tl, tm, l, min(r, tm), add);
    update((v << 1) + 1, tm + 1, tr, max(l, tm + 1), r, add);
    t[v] = t[v << 1] + t[(v << 1) + 1];
    return;
}

int find_sum(int v, int tl, int tr, int l, int r)
{
    if(l > r)
        return 0;
    push(v, tl, tr);
    if(l == tl && r == tr)
        return t[v];
    int tm = (tl + tr) >> 1;
    return find_sum(v << 1, tl, tm, l, min(r, tm)) + find_sum((v << 1) + 1, tm + 1, tr, max(l, tm + 1), r);
}

int intersection(int k1, int b1, int k2, int b2)
{
    int dk = k1 - k2;
    int db = b2 - b1;
    return db / dk + (db / dk > 0 && abs(db) % abs(dk) > 0);
}

struct ConvexHullTrick
{
    int sz = 0;
    vector < int > k, b, fr;
    void push(int newk, int newb)
    {
        while(sz)
        {
            if(k.back() == newk && b.back() > newb || k.back() != newk && fr.back() >= intersection(k.back(), b.back(), newk, newb))
            {
                sz--;
                k.pop_back();
                b.pop_back();
                fr.pop_back();
                continue;
            }
            break;
        }
        if(sz && k.back() == newk)
            return;
        fr.push_back((sz ? intersection(k.back(), b.back(), newk, newb) : -INF));
        k.push_back(newk);
        b.push_back(newb);
        sz++;
    }
    int convex(int x)
    {
        if(!sz)
            return INF;
        int j = upper_bound(fr.begin(), fr.end(), x) - fr.begin() - 1;
        return k[j] * x + b[j];
    }
};

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int t;
    cin >> t;
    while (t--)
    {
        int n;
        cin >> n;
        for (int i = 0; i < n; i++)
            cin >> a[i];
        ans.clear();
        for (int i = 0; i < n; i++)
        {
            int pos = (n - 1 + i) % n;
            int j = (pos - 4 + n) % n;
            int cnt = 0;
            while (a[pos] > 0)
            {
                cnt++;
                if (cnt == n * 2) break;
                if (a[j] > 0 && pos != j)
                {
                    ans.push_back({pos + 1, j + 1});
                    a[pos]--;
                    a[j]--;
                }
                j--;
                j += n;
                j %= n;
            }
        }
        cout << ans.size() << '\n';
        for (auto i : ans)
            cout << i.first << " " << i.second << '\n';
    }
}
