#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vll;
typedef vector<int> vi;
typedef vector<string> vs;
typedef vector<char> vc;
typedef pair<int, int> pii;
#define PUB emplace_back
#define POB pop_back
#define PUF emplace_front
#define POF pop_front
#define MP make_pair
#define MT make_tuple
#define LB lower_bound
#define F first
#define S second
#define f(i, a, b) for(int i = a; i < b; i++)
#define fr(i, a, b) for(int i = a; i > b; i--)
#define fl(i, a, b) for(ll i = a; i < b; i++)
#define frl(i, a, b) for(ll i = a; i > b; i--)
#define CY cout<<"YES"<<endl; 
#define CN cout<<"NO"<<endl;
#define ce(the_variable) cout<<the_variable<<endl;
#define cs(the_variable) cout<<the_variable<<" ";
#define PI 3.14159265358979323846
#define Sort(v) sort(begin(v),end(v))

void FAST() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}

int partition(vector<int>& v, int l, int r)
{
    int pivot_index = rand() % (r - l + 1) + l;
    swap(v[pivot_index], v[l]);
    int i = l + 1, j = l + 1;
    while (j <= r)
    {
        if (v[j] < v[l])
        {
            swap(v[j], v[i]);
            i++;
        }
        j++;
    }
    swap(v[l], v[i - 1]);
    return i;
}
int Rselect(vector<int>& v, int i, int l, int r)
{
    if (l == r)
        return v[l];
    int pivot = partition(v, l, r);
    if (pivot == i)
        return v[pivot - 1];
    else if (pivot < i)
    {
        return Rselect(v, i, pivot, r);
    }
    else
    {
        return Rselect(v, i, l, pivot - 2);
    }
}

template<typename T>
ostream& operator<<(ostream& stream, const vector<T>& vec) //outputting a vector
{
    for (auto& i : vec)
    {
        stream << i << ' ';
    }
    stream << '\n';
    return stream;
}

template<class T>
istream& operator>>(istream& stream, vector<T>& vec) //input for vectors of fixed size
{
	for (auto& i : vec)
	{
		stream >> i;
	}
	return stream;
}


ll Modpow(ll n,ll p,ll k){
    if(p == 0)
    return 1;
    ll result = 1;
    ll i = 1;
    while(i<=p)
    {
        result = (result*n)%k;
    }
    return result;
}
ll ModFact(ll n,ll p){
    if(n>=p)
    return 0;
    ll result = 1;
    f(i,1,n+1)
        result = (result*i) %p;
    return result;
}
ll MI(ll a, ll b,ll s0,ll s1){
    ll k = b;
    if(b == 0)return s0;
    else return  MI(b,a%b,s1,s0-s1*(a/b));
}
ll Choose(ll a,ll b,ll c){
    if(a<b)
    return 0;
    ll x = ModFact(a,c);
    ll y = ModFact(b,c);
    ll z = ModFact(a-b,c);
    ll y_ = MI(y,c,1,0);
    if(y_<0)
    y_ = y_+c;
    ll z_ = MI(z,c,1,0);
    if(z_<0)
    z_ = z_+c;
    ll mul = (x*y_)%c;
    mul = (mul*z_)%c;
    return mul;
}

bool isPrime(int a) {
    for(int i = 2; i * i <= a; ++i)
        if(a % i == 0)
            return false;
    return true;
}

ll phi(ll n){
    ll result = n;
    for (ll i = 2; i * i <= n; i++) {
        if (n % i == 0) {
            while (n % i == 0)
                n =n/ i;
            result =result - result / i;
        }
    }
    if (n > 1)
        result =result - result / n;
    return result;
}
ll gcd(ll a, ll b)
{
    if (b == 0)
        return a;
    return gcd(b, a % b); 
     
}
ll findGCD(vll &arr, ll n) 
{ 
    ll result = arr[0]; 
    for (ll i = 1; i < n; i++) 
    { 
        result = gcd(arr[i], result); 
  
        if(result == 1) 
        { 
           return 1; 
        } 
    } 
    return result; 
} 
template<typename T>
void pop_front(std::vector<T> &v)
{
    if (v.size() > 0) {
        v.erase(v.begin());
    }
}
void solve()
{
    vector<pii> inp;
    set <pii > :: iterator it;
    int n,a;
    bool yes=false;
    cin>>n;
    f(i,0,n*2){
        cin>>a;
        inp.PUB(MP(a,i));
    }
    Sort(inp);
    
    pii ma,ma2,ma3;
    int x,tem;
    ma=inp.back();
    inp.POB();
    
    f(jj,0,2*n-1){
        set<pii> A;
        vector<pii> ans;
        f(i,0,2*n-1)
            A.insert(inp[i]);
        
        bool poss=true;
        ma2=inp[jj];
        A.erase(ma2);
        x=ma.F;

        while(A.size()){
            //cs("x ")ce(x)
            ma3=*A.rbegin();
            A.erase(*A.rbegin());
            //cs("ma3 ")ce(ma3.F)
            tem=x-ma3.F;
            //cs("tem ")ce(tem)
            it= A.upper_bound(MP(tem,INT_MAX));
            if(it==A.begin()){
                poss=false;
                break;
            }
            it--;
            if(it->F!=tem){
                poss=false;
                break;
            }
            ans.PUB(MP(it->F,ma3.F));
            x=ma3.F;
            A.erase(*it);
            //for(auto i:A){cs((i.F))}ce(" y")

        }
        if(A.size())ma2=MP(A.begin()->F,0);
        if(poss){
            CY
            ce(ma.F+ma2.F)
            cs(ma.F)ce(ma2.F)
            for(auto i:ans){
                cs((i.F))ce((i.S));
            }
            return;
        }
    }
    CN;


}


void SOLT(){
    int test=1;
    cin>>test;
    while(test--)solve();
}
int main(){    
    FAST();   
    SOLT();
    return 0;
}


