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

#define int long long
#define ull unsigned long long
#define N 20000001
#define endl "\n"

/*
vector <bool> prime(N + 1, true) ;
vector <ull> fac(N) ;
vector <ull> inverse_fac(N) ;


bool check_prime(int n){
	if(n == 1)
		return false ;
	if(n % 2 == 0)
		return false ;
	for(int i = 3; i <= sqrt(n); i += 2){
		if(n % i == 0)
			return false ;
	}
	return true ;
}

void SieveOfEratosthenes(int n) {
	prime[0] = false ;
	prime[1] = false ;
	for (int i = 2; i * i <= n; i++) {
		if (prime[i] == true) {
			for (int j = i * i; j <= n; j += i)
				prime[j] = false;
		}
	}
	return ;
}

void calc_fact(ull mod) {
	fac[0] = 1;
	for (int i = 1; i < N; i++)
		fac[i] = (fac[i - 1] * i) % mod;
}

ull mod_expo(ull a, ull n, ull mod) {
	ull res{1} ;
	a = a % mod;
	while (n) {
		if (n & 1)
			res = (res * a) % mod;
		n = n >> 1;
		a = (a * a) % mod ;
	}
	return res % mod;
}

ull modInverse(ull n, ull mod) {
	return mod_expo(n, mod - 2, mod);
}

void calc_inverse_fact(ull mod) {
	inverse_fac[N - 1] = modInverse(fac[N - 1], mod) ;
	for (int i = N - 2; i >= 0; i--) {
		inverse_fac[i] = (inverse_fac[i + 1] * (i + 1)) % mod ;
	}
}


ull nCr_mod_fermat1(ull n, ull r, ull mod) {
	if (n < r)
		return 0;
	if (r == 0)
		return 1;
	ull res{fac[n]} ;
	res = (res * modInverse(fac[r], mod)) % mod ;
	res = (res * modInverse(fac[n - r], mod)) % mod ;
	return res ;
}

ull nCr_mod_fermat2(ull n, ull r, ull mod) {
	if (n < r)
		return 0;
	if (r == 0)
		return 1;
	ull res{fac[n]} ;
	res = (res * inverse_fac[r]) % mod ;
	res = (res * inverse_fac[n - r]) % mod ;
	return res ;
}


int extended_gcd(int a, int b, int *x, int *y) {
	if (a == 0) {
		*x = 0;
		*y = 1;
		return b;
	}
	int x1{}, y1{} ;
	int gcd = extended_gcd(b % a, a, &x1, &y1);
	*x = y1 - (b / a) * x1;
	*y = x1;
	return gcd;
}


vector <int> find_next_greater_element(vector <int> &vec) {
	int n{} ;
	n = vec.size() ;
	vector <int> res(n, -1) ;
	stack <int> st{} ;
	st.push(n - 1);
	for (int i = n - 2; i >= 0; i--) {
		while (!st.empty() && vec[st.top()] <= vec[i])
			st.pop();
		if (!st.empty())
			res[i] = st.top() ;
		st.push(i);
	}
	return res ;
}

vector <int> find_prev_smaller_element(vector <int> &vec) {
	int n{} ;
	n = vec.size() ;
	vector <int> res(n, -1) ;
	stack <int> st{} ;
	st.push(0);
	for (int i = 1; i < n; i++) {
		while (!st.empty() && vec[st.top()] >= vec[i])
			st.pop();
		if (!st.empty())
			res[i] = st.top() ;
		st.push(i);
	}
	return res ;
}

struct custom_hash {
	static uint64_t splitmix64(uint64_t x) {
		x += 0x9e3779b97f4a7c15;
		x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
		x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
		return x ^ (x >> 31);
	}

	size_t operator()(uint64_t x) const {
		static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
		return splitmix64(x + FIXED_RANDOM);
	}
};

// user defined comp for sets etc.
struct comp {
	bool operator()(const pair <int, int> &p1, const pair <int, int> &p2) {
		if (p1.first != p2.first)
			return p1.first < p2.first ;
		return p1.second > p2.second ;
	}
} ;


#define INF 1e18


// Counting no of inversions using a segment tree
vector <int> st(400004) ;              // sum of a segment

void build_st(int si, int ss, int se, vector <int> &vis) {
	if (ss == se) {
		st[si] = vis[ss] ;
		return ;
	}
	int mid{} ;
	mid = (ss + (se - ss) / 2) ;
	build_st(2 * si, ss, mid, vis) ;
	build_st(2 * si + 1, mid + 1, se, vis) ;
	st[si] = st[2 * si] + st[2 * si + 1] ;
}

int query_st(int si, int ss, int se, int qs, int qe, vector <int> &vis) {
	if (qs > se || qe < ss)
		return 0 ;
	else if (qs <= ss && qe >= se)
		return st[si] ;
	int mid{} ;
	mid = ss + (se - ss) / 2 ;
	int l{}, r{} ;
	l = query_st(2 * si, ss, mid, qs, qe, vis) ;
	r = query_st(2 * si + 1, mid + 1, se, qs, qe, vis) ;
	return l + r ;
}

void point_update_st(int si, int ss, int se, int qi, vector <int> &vis) {
	if (ss == se) {
		st[si] = vis[se] ;
		return ;
	}
	int mid{} ;
	mid = ss + (se - ss) / 2 ;
	if (qi <= mid)
		point_update_st(2 * si, ss, mid, qi, vis) ;
	else
		point_update_st(2 * si + 1, mid + 1, se, qi, vis) ;
	st[si] = st[2 * si] + st[2 * si + 1] ;
}
*/

vector <ull> fac(100001) ;

void calc_fact(ull mod) {
	fac[0] = 1;
	for (int i = 1; i < 100001; i++)
		fac[i] = (fac[i - 1] * i) % mod;
}

ull mod_expo(ull a, ull n, ull mod) {
	ull res{1} ;
	a = a % mod;
	while (n) {
		if (n & 1)
			res = (res * a) % mod;
		n = n >> 1;
		a = (a * a) % mod ;
	}
	return res % mod;
}

ull modInverse(ull n, ull mod) {
	return mod_expo(n, mod - 2, mod);
}

ull nCr_mod_fermat1(ull n, ull r, ull mod) {
	if (n < r)
		return 0;
	if (r == 0)
		return 1;
	ull res{fac[n]} ;
	res = (res * modInverse(fac[r], mod)) % mod ;
	res = (res * modInverse(fac[n - r], mod)) % mod ;
	return res ;
}

struct custom_hash {
	static uint64_t splitmix64(uint64_t x) {
		x += 0x9e3779b97f4a7c15;
		x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
		x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
		return x ^ (x >> 31);
	}

	size_t operator()(uint64_t x) const {
		static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
		return splitmix64(x + FIXED_RANDOM);
	}
};


// Function to return the count
// of all valid pairs
int countPairs(vector <int> &vec, int n) {
	// To store the frequencies
	// of (arr[i] - i)
	unordered_map<int, int, custom_hash> mp;
	for (int i = 0; i < n; i++)
		mp[vec[i] - i]++;
	// To store the required count
	int res = 0;
	for (auto x : mp) {
		int cnt = x.second;
		// If cnt is the number of elements
		// whose differecne with their index
		// is same then ((cnt * (cnt - 1)) / 2)
		// such pairs are possible
		res += ((cnt * (cnt - 1)) / 2);
	}
	return res;
}

// while (q--) {
// 			int k{} ;
// 			cin >> k ;
// 			int start{1}, mid{}, end{n} ;
// 			int ans{} ;
// 			while (start <= end) {
// 				mid = (start + (end - start) / 2) ;
// 				cout << "? " << start << " " << mid << endl ;
// 				cout.flush() ;
// 				int num{} ;
// 				cin >> num ;
// 				int len{} ;
// 				len = mid - start + 1 ;
// 				if (k <= (len - num)) {
// 					ans = mid ;
// 					end = mid - 1 ;
// 				}
// 				else {
// 					k -= (len - num) ;
// 					start = mid + 1 ;
// 				}
// 			}
// 			cout << "! " << ans << endl ;
// 		}


//vector <int> prime{} ;
vector <int> primes{} ;

// This functions finds all
// primes smaller than limit
// using simple sieve of eratosthenes.
// It stores found
// primes in vector prime[]
void simpleSieve(int limit, vector<int>& prime)
{
	bool mark[limit + 1];
	memset(mark, false, sizeof(mark));

	for (int i = 2; i * i <= limit; ++i)
	{
		if (mark[i] == false)
		{
			// If not marked yet, then its a prime
			prime.push_back(i);
			for (int j = i; j <= limit; j += i)
				mark[j] = true;
		}
	}
}



// Finds all prime numbers
// in given range using
// segmented sieve
void primesInRange(int low, int high)
{

	// Compute all primes smaller or equal to
	// square root of high using simple sieve
	int limit = floor(sqrt(high)) + 1;
	vector<int> prime;
	simpleSieve(limit, prime);
	cout << prime.size() << endl ;
	// Count of elements in given range
	int n = high - low + 1;

	// Declaring boolean only for [low, high]
	bool mark[n + 1];
	memset(mark, false, sizeof(mark));

	// Use the found primes by
	// simpleSieve() to find
	// primes in given range
	for (int i = 0; i < prime.size(); i++)
	{

		// Find the minimum number
		// in [low..high] that is
		// a multiple of prime[i]
		// (divisible by prime[i])
		int loLim = floor(low / prime[i]) * prime[i];
		if (loLim < low)
			loLim += prime[i];
		if (loLim == prime[i])
			loLim += prime[i];

		/* Mark multiples of prime[i]
			in [low..high]:
			We are marking j - low
			for j, i.e. each number
			in range [low, high] is
			mapped to [0, high - low]
			so if range is [50, 100]
			marking 50 corresponds
			to marking 0, marking
			51 corresponds to 1 and
			so on.Also if the current j
			is prime don't mark
			it as true.In this way we need
			to allocate space only
			for range */
		for (int j = loLim; j <= high; j += prime[i])
			mark[j - low] = true;
	}

	// Numbers which are not marked
	// in range, are prime
	for (int i = low; i <= high; i++)
		if (!mark[i - low])
			primes.push_back(i) ;
}

//vector <bool> prime(10000001, true) ;

// void SieveOfEratosthenes(int n) {
// 	prime[0] = false ;
// 	prime[1] = false ;
// 	for (int i = 2; i * i <= n; i++) {
// 		if (prime[i] == true) {
// 			for (int j = i * i; j <= n; j += i)
// 				prime[j] = false;
// 		}
// 	}
// 	return ;
// }

vector<long long> segmentedSieve(long long L, long long R) {
	// generate all primes up to sqrt(R)
	long long lim = sqrt(R);
	vector<bool> mark(lim + 1, false);
	vector<long long> primes;
	for (long long i = 2; i <= lim; ++i) {
		if (!mark[i]) {
			primes.emplace_back(i);
			for (long long j = i * i; j <= lim; j += i)
				mark[j] = true;
		}
	}

	vector<bool> isPrime(R - L + 1, true);
	for (long long i : primes)
		for (long long j = max(i * i, (L + i - 1) / i * i); j <= R; j += i)
			isPrime[j - L] = false;
	if (L == 1)
		isPrime[0] = false;
	vector <long long> res{} ;
	for (int i = L; i <= R; i++) {
		if (isPrime[i - L])
			res.push_back(i) ;
	}
	return res ;
}

int32_t main() {
#ifndef ONLINE_JUDGE
	freopen("input1.txt", "r", stdin) ;

	freopen("output1.txt", "w", stdout) ;
#endif
	ios_base::sync_with_stdio(false) ;
	cin.tie(NULL) ;
	// SieveOfEratosthenes(10000000) ;
	// for (int i = 1; i <= 10000000; i++) {
	// 	if (prime[i])
	// 		primes.push_back(i) ;
	// }
	//primesInRange(100001, 200001) ;
	//primes = segmentedSieve(1000000001, 1003000000) ;
	// for (auto elem : primes)
	// 	cout << elem << " " ;
	// cout << endl ;
	int t{} ;
	cin >> t ;
	while (t--) {
		int n{} ;
		cin >> n ;
		vector <int> vec(n, 0) ;
		int min_elem_idx{ -1}, min_elem{LLONG_MAX} ;
		for (int i = 0; i < n; i++) {
			cin >> vec[i] ;
			if (vec[i] < min_elem) {
				min_elem_idx = i ;
				min_elem = vec[i] ;
			}
		}
		vector <vector <int>> res{} ;
		for (int i = 0; i < n; i++) {
			if (i != min_elem_idx)
				res.push_back({min_elem_idx + 1, i + 1, min_elem, min_elem + abs(i - min_elem_idx)}) ;
		}
		cout << res.size() << endl ;
		for (auto v : res) {
			for (auto elem : v)
				cout << elem << " " ;
			cout << endl ;
		}
	}
	return 0 ;
}
