description: An important meeting is to be held and there are exactly n people invited. At any moment, any two people can step back and talk in private. The same two people can talk several (as many as they want) times per meeting.
  
  Each person has limited sociability. The sociability of the i-th person is a non-negative integer a_i. This means that after exactly a_i talks this person leaves the meeting (and does not talk to anyone else anymore). If a_i = 0, the i-th person leaves the meeting immediately after it starts.
  
  A meeting is considered most productive if the maximum possible number of talks took place during it.
  
  You are given an array of sociability a, determine which people should talk to each other so that the total number of talks is as large as possible.
  
  Input
  
  The first line contains an integer t (1 ≤ t ≤ 1000) — the number of test cases.
  
  The next 2t lines contain descriptions of the test cases.
  
  The first line of each test case description contains an integer n (2 ≤ n ≤ 2 ⋅ 10^5) —the number of people in the meeting. The second line consists of n space-separated integers a_1, a_2, ..., a_n (0 ≤ a_i ≤ 2 ⋅ 10^5) — the sociability parameters of all people. 
  
  It is guaranteed that the sum of n over all test cases does not exceed 2 ⋅ 10^5. It is also guaranteed that the sum of all a_i (over all test cases and all i) does not exceed 2 ⋅ 10^5.
  
  Output
  
  Print t answers to all test cases.
  
  On the first line of each answer print the number k — the maximum number of talks possible in a meeting.
  
  On each of the next k lines print two integers i and j (1 ≤ i, j ≤ n and i ≠ j) — the numbers of people who will have another talk.
  
  If there are several possible answers, you may print any of them.
  
  Example
  
  Input
  
  
  8
  2
  2 3
  3
  1 2 3
  4
  1 2 3 4
  3
  0 0 2
  2
  6 2
  3
  0 0 2
  5
  8 2 0 1 1
  5
  0 1 0 0 6
  
  
  Output
  
  
  2
  1 2
  1 2
  3
  1 3
  2 3
  2 3
  5
  1 3
  2 4
  2 4
  3 4
  3 4
  0
  2
  1 2
  1 2
  0
  4
  1 2
  1 5
  1 4
  1 2
  1
  5 2
solution: import java.util.*;
  import java.lang.*;
  import java.io.*;
  import java.math.BigInteger;
  import java.io.BufferedReader;
  import java.io.BufferedWriter;
  import java.io.DataInputStream;
  import java.io.FileInputStream;
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.io.OutputStreamWriter;
  import java.math.BigInteger;
  import java.util.List;
  import java.util.Map;
  import java.util.Map.Entry;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.Collections;
  import java.util.Comparator;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Iterator;
  public class h
  {		public static int mod=1000000007;
  	 static class Reader {
  		 
  	        final private int BUFFER_SIZE = 1 << 16;
  	        private DataInputStream din;
  	        private byte[] buffer;
  	        private int bufferPointer, bytesRead;
  	 
  	        public Reader()
  	        {
  	            din = new DataInputStream(System.in);
  	            buffer = new byte[BUFFER_SIZE];
  	            bufferPointer = bytesRead = 0;
  	        }
  	 
  	        public Reader(String file_name) throws IOException
  	        {
  	            din = new DataInputStream(
  	                new FileInputStream(file_name));
  	            buffer = new byte[BUFFER_SIZE];
  	            bufferPointer = bytesRead = 0;
  	        }
  	 
  	        public String readLine() throws IOException
  	        {
  	            byte[] buf = new byte[64]; // line length
  	            int cnt = 0, c;
  	            while ((c = read()) != -1) {
  	                if (c == '\n') {
  	                    if (cnt != 0) {
  	                        break;
  	                    }
  	                    else {
  	                        continue;
  	                    }
  	                }
  	                buf[cnt++] = (byte)c;
  	            }
  	            return new String(buf, 0, cnt);
  	        }
  	 
  	        public int nextInt() throws IOException
  	        {
  	            int ret = 0;
  	            byte c = read();
  	            while (c <= ' ') {
  	                c = read();
  	            }
  	            boolean neg = (c == '-');
  	            if (neg)
  	                c = read();
  	            do {
  	                ret = ret * 10 + c - '0';
  	            } while ((c = read()) >= '0' && c <= '9');
  	 
  	            if (neg)
  	                return -ret;
  	            return ret;
  	        }
  	 
  	        public long nextLong() throws IOException
  	        {
  	            long ret = 0;
  	            byte c = read();
  	            while (c <= ' ')
  	                c = read();
  	            boolean neg = (c == '-');
  	            if (neg)
  	                c = read();
  	            do {
  	                ret = ret * 10 + c - '0';
  	            } while ((c = read()) >= '0' && c <= '9');
  	            if (neg)
  	                return -ret;
  	            return ret;
  	        }
  	 
  	        public double nextDouble() throws IOException
  	        {
  	            double ret = 0, div = 1;
  	            byte c = read();
  	            while (c <= ' ')
  	                c = read();
  	            boolean neg = (c == '-');
  	            if (neg)
  	                c = read();
  	 
  	            do {
  	                ret = ret * 10 + c - '0';
  	            } while ((c = read()) >= '0' && c <= '9');
  	 
  	            if (c == '.') {
  	                while ((c = read()) >= '0' && c <= '9') {
  	                    ret += (c - '0') / (div *= 10);
  	                }
  	            }
  	 
  	            if (neg)
  	                return -ret;
  	            return ret;
  	        }
  	 
  	        private void fillBuffer() throws IOException
  	        {
  	            bytesRead = din.read(buffer, bufferPointer = 0,
  	                                 BUFFER_SIZE);
  	            if (bytesRead == -1)
  	                buffer[0] = -1;
  	        }
  	 
  	        private byte read() throws IOException
  	        {
  	            if (bufferPointer == bytesRead)
  	                fillBuffer();
  	            return buffer[bufferPointer++];
  	        }
  	 
  	        public void close() throws IOException
  	        {
  	            if (din == null)
  	                return;
  	            din.close();
  	        }
  	 }
  	 public static long gcd(long x, long p)
  	    {
  	        if (x == 0)
  	            return p;
  	         
  	        return gcd(p%x, x);
  	    }
  	 public static HashMap<Integer, Integer> sortByValue(HashMap<Integer, Integer> hm)
  	    {
  	        // Create a list from elements of HashMap
  	        List<Map.Entry<Integer, Integer> > list =
  	               new LinkedList<Map.Entry<Integer, Integer> >(hm.entrySet());
  	 
  	        // Sort the list
  	        Collections.sort(list, new Comparator<Map.Entry<Integer, Integer> >() {
  	            public int compare(Map.Entry<Integer, Integer> o1,
  	                               Map.Entry<Integer, Integer> o2)
  	            {
  	                return (o1.getValue()).compareTo(o2.getValue());
  	            }
  	        });
  	         
  	        // put data from sorted list to hashmap
  	        HashMap<Integer, Integer> temp = new LinkedHashMap<Integer, Integer>();
  	        for (Map.Entry<Integer, Integer> aa : list) {
  	            temp.put(aa.getKey(), aa.getValue());
  	        }
  	        return temp;
  	    }
  	 static int sieve =  1000000 ;
   
   
  	 static boolean[] prime =  new boolean[sieve + 1] ;
   
  	 public static void sieveOfEratosthenes() 
  	     { 
  	         // FALSE == prime and 1 // TRUE ==  COMPOSITE
  	         
  	         // time complexity = 0(NlogLogN)== o(N)
  	         
  	         // gives prime nos bw 1 to N // size - 1e7(at max)
  	         
  	         for(int i = 4; i<= sieve ; i++)
  	         {
  	             prime[i] = true  ; i++ ;
  	            
  	         }
  	         
  	         for(int p = 3; p*p <= sieve; p++) 
  	         { 
  	            if(prime[p] == false) 
  	             { 
  	                     for(int i = p*p; i <= sieve; i += p) 
  	                     prime[i] = true; 
  	             } 
  	             
  	             p++ ;
  	         } 
  	           
  	     } 
  	 public static void arrInpInt(int [] arr, int n) throws IOException
  	 {
  		 Reader reader = new Reader();
  		 for(int i=0;i<n;i++)
  	   		{
  	   			arr[i]=reader.nextInt();	
  	   		}
  	 }
  	 public static void arrInpLong(long [] arr, int n) throws IOException
  	 {
  		 Reader reader = new Reader();
  		 for(int i=0;i<n;i++)
  	   		{
  	   			arr[i]=reader.nextLong();	
  	   		}
  	 }
  	 public static void printArr(int[] arr)
  	 {
  		 for(int i=0;i<arr.length;i++)
  		 {
  			 System.out.print(arr[i]+" ");
  		 }
  		 System.out.println();
  	 }
  	 public static int[] decSort(int[] arr)
  	 {
  		  int[] arr1 = Arrays.stream(arr).boxed().sorted(Collections.reverseOrder()).mapToInt(Integer::intValue).toArray();	
  		  return arr1;
  	 }
  	 
  	
  	//if present - return the first occurrence of the no
  	//not present- return the index of next greater value 
  	//if greater than all the values return N(taking high=N-1)
  	//if smaller than all the values return 0(taking low =0)
  	static int lower_bound(int arr[], int low,int high, int X)
  	{
   
  	 if (low > high) {
  	     return low;
  	 }
  	 int mid = low + (high - low) / 2;
  	 if (arr[mid] >= X) {
  	     return lower_bound(arr, low,
  	                        mid - 1, X);
  	 }
   
  	 return lower_bound(arr, mid + 1,
  	                    high, X);
  	}
  	//if present - return the index of next greater value
  	//not present- return the index of next greater value 
  	//if greater than all the values return N(taking high=N-1)
  	//if smaller than all the values return 0(taking low =0)\
  	
  	static int upper_bound(int arr[], int low, int high, int X)
  {
   
  if (low > high)
      return low;
   
  int mid = low + (high - low) / 2;
  if (arr[mid] <= X) {
      return upper_bound(arr, mid + 1,
                         high, X);
  }
   
  return upper_bound(arr, low,
                     mid - 1, X);
  }
  	
  	
  	 public static class Pair  {// comparator with class
  		    int x;
  		    int y;
  		 public Pair(int x, int y)
  		    {
  		        this.x = x;
  		        this.y = y;
  		    }
  		}
  	 
  	 public static void sortbyColumn(int arr[][], int col)  // send 2d array and col no
  	    {
  	        Arrays.sort(arr, new Comparator<int[]>() {       
  	          @Override              
  	          public int compare(final int[] entry1, 
  	                             final int[] entry2) {
  	            if (entry1[col] > entry2[col])
  	                return 1;
  	            else if (entry1[col] < entry2[col])
  	                return -1;
  	              else return 0;
  	          }
  	        });
  	    }
  	 public static void sortbyColumn1(int arr[][], int col)  // send 2d array and col no
  	    {
  	        Arrays.sort(arr, new Comparator<int[]>() {       
  	          @Override              
  	          public int compare(final int[] entry1, 
  	                             final int[] entry2) {
  	            if (entry1[col] > entry2[col])
  	                return 1;
  	            else if (entry1[col] < entry2[col])
  	                return -1;
  	            else if(entry1[col] == entry2[col])
  	            {
  	            	if(entry1[col-1]>entry2[col-1])
  	            		return -1;
  	            	else if(entry1[col-1]<entry2[col-1])
  	            		return 1;
  	            	else return 0;
  	            }
  	              else return 0;
  	          }
  	        });
  	    }
  	 public static void print2D(int mat[][])
  	    {
  	        // Loop through all rows
  	        for (int i = 0; i < mat.length; i++)
  	 
  	        {  // Loop through all elements of current row
  	        {
  	            for (int j = 0; j < mat[i].length; j++)
  	                System.out.print(mat[i][j] + " ");
  	        }
  	            System.out.println();
  	        }
  	    }
  	     
  	    public static class  p
  	     {
  	    	 int no;
  	    	 int h;
  	    	 public p(int no, long h)
  	    	 {
  	    		 this.no=no;
  	    		 this.h=(int) h;
  	    	 }
  	     }
  	    
  	  static    class com implements Comparator<p>{
  	            public int compare(p s1, p s2) {
  	                if (s1.h > s2.h)
  	                    return -1;
  	                else if (s1.h < s2.h)
  	                    return 1;
  	                else if(s1.h==s2.h)
  	                {
  	                	if(s1.no>s2.no)return -1;
  	                	else return 1;
  	                }
  	                                return 0;
  	                }
  	        }
  	  
   
  	  
   	public static void main(String args[]) throws NumberFormatException, IOException ,java.lang.Exception
  	{
  		
  		Reader reader = new Reader();
  		
  		
  		//sieveOfEratosthenes();
  		//System.out.println(prime[0]+" "+prime[1]+" "+prime[2]+" "+prime[3]+" "+prime[4]);
  		//Scanner reader=new Scanner(System.in);
  		
  		//BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
  		//int cases=Integer.parseInt(br.readLine());
  		//int cases=1;
  		int cases=reader.nextInt();
  		
     	while (cases-->0){
     		int N=reader.nextInt();
     		//BufferedWriter output = new BufferedWriter(new OutputStreamWriter(System.out));
    // 		int P=reader.nextInt();
     		//int[][] arr=new int[N][N];
     	//	int K=reader.nextInt();
     		//int X=reader.nextInt();
     		//int K=reader.nextInt();
     		//int S=reader.nextInt();
     		//int circum=reader.nextInt();
     		//int K=reader.nextInt();
  //   		String[] first=br.readLine().split(" ");
  //   		int N=Integer.parseInt(first[0]);
  //   		int P=Integer.parseInt(first[1]);
  //   		int K=Integer.parseInt(first[2]);
     		//String[] first=br.readLine().split(" ");
     		//int N=Integer.parseInt(first[0]);
     		//int K=Integer.parseInt(first[1]);
     		//int X=reader.nextInt();
     		//int Y=reader.nextInt();
     		//String s2=br.readLine();
     		//String s3=br.readLine();
     		//char[]  s11=s2.toCharArray();
     		//String[] first1=br.readLine().split(" ");
     		//int C=Integer.parseInt(first1[0]);
     		//int C1=Integer.parseInt(first1[1]);
     		//char[]  s12=s3.toCharArray();
      	//int max=Integer.MIN_VALUE;
     		//int min=Integer.MAX_VALUE;
     		//int ind=-1;
     		//HashMap<Integer,Integer> a1=new HashMap<Integer,Integer>();
     		//HashMap<Long,Long> b1=new HashMap<Long,Long>();
     		//HashMap<Integer,Integer> boy=new HashMap<Integer,Integer>();
     		//HashMap<Integer,Integer> map=new HashMap<Integer,Integer>();
     		//TreeSet<Integer> tree =new TreeSet<Integer>(); 
     		//TreeSet<Long> a =new TreeSet<Long>();
     		//TreeSet<Long> b =new TreeSet<Long>();
     		//HashSet<Integer> map=new HashSet<Integer>();
     		//int[] arr=new int[N];
     		//int[] arr1=new int[N];
     		//ArrayList<Integer> no=new ArrayList<Integer>();
     		//ArrayList<Long> sum=new ArrayList<Long>();
     		//int [][] arr=new int[K][2];
          //System.out.println(map);
     		PriorityQueue<p> Q=new PriorityQueue<p>(new com());
     		//PriorityQueue<Long> w=new PriorityQueue<Long>();
     		//int [] arr=new int[K];
     		for (int i=0;i<N;i++)
     		{
     			int inp=reader.nextInt();
     			if(inp!=0)Q.add(new p(i+1,inp));
     		}
     		long x=0;
     	    ArrayList<p> ans=new ArrayList<p>();
     		while(Q.size()>=2)
     		{
     		 p p1=Q.remove();
     		 p p2=Q.remove();
     		//System.out.println(p1.h+" "+p2.h);
     		p1.h=p1.h-1;
     		p2.h=p2.h-1;
     		x++;
     		//output.write(p1.no+" "+p2.no);
     		ans.add(new p(p1.no,p2.no));		 
     		if(p1.h!=0)Q.add(p1);
     		if(p2.h!=0)Q.add(p2);
     		
     		 
     		}
     		System.out.println(x);
     		for (int i=0;i<ans.size();i++)
     		{
     			p k= ans.get(i);
     			System.out.println(k.h+" "+k.no);
     		}
     		}
          //System.out.println(Arrays.toString(sum));    
     		
     	}}