#include<cstdlib>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<vector>
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)>(b))?(b):(a))
#define sign(x) ((x)>eps?1:((x)<-eps?(-1):(0))) //��ź���
using namespace std;
const int MAXN=1000;
const double eps=1e-8,inf=1e50;
struct point {
    double x,y;
    point() {}
    point(double _x,double _y) {
        x=_x;
        y=_y;
    }
};
inline double xmult(point o,point a,point b) {
    return (a.x-o.x)*(b.y-o.y)-(b.x-o.x)*(a.y-o.y);
}
inline double xmult(double x1,double y1,double x2,double y2) {
    return x1*y2-x2*y1;
}
inline double getdist2(point a,point b){
    double dx=a.x-b.x,dy=a.y-b.y;
    return dx*dx+dy*dy;
}
inline double getdist(point a,point b){
    return sqrt(getdist2(a,b));
}
double minlen(vector<point> tri){
    double len=inf;
    for(int i=0;i<3;i++){
        len=min(len,getdist2(tri[i],tri[(i+1)%3]));
    }
    return len;
}
bool comp_cod(const point a,const point b){
    return a.x<b.x||((sign(a.x-b.x)==0)&&a.y<b.y);
}
vector<point> adjust_convex_hull(vector<point> p,int first){
    int i,j,k,id;
    vector<point> pg;
    for(i=0;i<first;i++){
        pg.push_back(p[i]);
    }
    double mf;
    for(j=first;j<p.size();){
        i=j;
        pg.push_back(p[j++]);
        pg.push_back(p[j++]);
        while(j<p.size()&&sign(xmult(p[i],p[i+1],p[j]))==0){
            j++;
        }
        j--;
        if(sign(xmult(p[i],p[i+1],p[j]))==0&&j-i+1>3)
        {
            mf=0;id=-1;
            for(k=i+1;k<j;k++){
                double tmp=min(getdist2(p[i],p[k]),getdist2(p[k],p[j]));
                if(tmp>mf){
                    mf=tmp;
                    id=k;
                }
            }
            pg.pop_back();
            pg.push_back(p[id]);
            pg.push_back(p[j++]);
        }
        else if(j!=i+1){
            pg.push_back(p[j++]);
        }
        else
            j++;
    }
    return pg;
}
vector<point> convex_hull(vector<point> p){
    int i,j,top;
    sort(p.begin(),p.end(),comp_cod);
    vector<point> pg;
    for(i=top=0;i<p.size();i++)
    {
        while(top>1&&xmult(pg[top-2],pg[top-1],p[i])<-eps)
            pg.pop_back(),top--;
        pg.push_back(p[i]),top++;
    }
    pg=adjust_convex_hull(pg,0);
    j=top=pg.size();
    for(i=p.size()-2;i>=0;i--)
    {
        while(top>j&&xmult(pg[top-2],pg[top-1],p[i])<-eps)
            pg.pop_back(),top--;
        pg.push_back(p[i]),top++;
    }
    pg.pop_back();
    pg=adjust_convex_hull(pg,j-1);
    return pg;
}
vector<point> make_tri(point a,point b,point c){
    vector<point> tri;
    tri.push_back(a);
    tri.push_back(b);
    tri.push_back(c);
    return tri;
}
int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        vector<point> p;
        point tmp;
        for(int i=0;i<n;i++){
            scanf("%lf%lf",&tmp.x,&tmp.y);
            p.push_back(tmp);
        }
        p=convex_hull(p);
        /*n=p.size();
        printf("size:%d\n",n);
        for(int i=0;i<n;i++){
            printf("(%.2lf %.2lf)\n",p[i].x,p[i].y);
        }*/
        //p=adjust_convex_hull(p);
        n=p.size();
        /*printf("size:%d\n",n);
        for(int i=0;i<n;i++){
            printf("(%.2lf %.2lf)\n",p[i].x,p[i].y);
        }*/
        double ans=0;
        for(int i=0;i<n-2;i++){
            for(int j=i+1;j<n-1;j++){
                for(int k=j+1;k<n;k++){
                    ans=max(ans,minlen(make_tri(p[i],p[j],p[k])));
                }
            }
        }
        printf("%lf\n",sqrt(ans)/2.0);
    }
    return 0;
}


#include<cstdlib>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<vector>
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)>(b))?(b):(a))
#define sign(x) ((x)>eps?1:((x)<-eps?(-1):(0))) //��ź���
using namespace std;
const int MAXN=4000;
const double eps=1e-8,inf=1e50,Pi=acos(-1.0);
struct point {
    double x,y;
    point() {}
    point(double _x,double _y) {
        x=_x;
        y=_y;
    }
} o,po[MAXN];
inline double xmult(point o,point a,point b) {
    return (a.x-o.x)*(b.y-o.y)-(b.x-o.x)*(a.y-o.y);
}
inline double xmult(double x1,double y1,double x2,double y2) {
    return x1*y2-x2*y1;
}
inline double getdist2(point a,point b) {
    double dx=a.x-b.x,dy=a.y-b.y;
    return dx*dx+dy*dy;
}
struct data{
    double x,y,angle,dist2;
    data(){}
    data(double _x,double _y,double _a,double _d){
        x=_x;
        y=_y;
        angle=_a;
        dist2=_d;
    }
}temp[MAXN];
bool comp_angle(const data a,const data b) {
   int tmp=sign(a.angle-b.angle);
   if(tmp<0||(tmp==0&&a.dist2<b.dist2))return true;
   else return false;
}
double seg[MAXN*4];
void build(int now,int left,int right){
    if(left==right){
        seg[now]=temp[left].dist2;
        return;
    }
    else{
        int lc=now<<1,rc=lc|1,mid=(left+right)>>1;
        build(lc,left,mid);
        build(rc,mid+1,right);
        seg[now]=max(seg[lc],seg[rc]);
    }
}
double getmax(int now,int left,int right,int ll,int rr){
    if(ll>rr)return 0;
    if(left==ll&&right==rr){
        return seg[now];
    }
    int lc=now<<1,rc=lc|1,mid=(left+right)>>1;
    if(rr<=mid)return getmax(lc,left,mid,ll,rr);
    else if(ll>mid)return getmax(rc,mid+1,right,ll,rr);
    else{
        return max(getmax(lc,left,mid,ll,mid),getmax(rc,mid+1,right,mid+1,rr));
    }
}
double ans;
void solve(int n,int center){
    int num=0;
    bool flag=false;
    for(int i=0;i<n;i++){
        if(i==center)continue;
        temp[num]=data(po[i].x,po[i].y,atan2(po[i].y-po[center].y,po[i].x-po[center].x),getdist2(po[i],po[center]));
        if(temp[num].dist2>ans)
            flag=true;
        num++;
    }
    if(!flag)return;
    sort(temp,temp+num,comp_angle);
    temp[num].angle=inf;
    build(1,0,num-1);
    for(int i=0;i<num;i++){
        int ll=i+1,rr=num,mid,lp,rp;
        while(ll<rr){
            mid=(ll+rr)>>1;
            if(temp[mid].angle-temp[i].angle>Pi/3.0-eps)
                rr=mid;
            else
                ll=mid+1;
        }
        if(rr==num)
            break;
        lp=rr;
        ll=i+1,rr=num;
        while(ll<rr){
            mid=(ll+rr)>>1;
            if(temp[mid].angle-temp[i].angle>5.0*Pi/3.0+eps)
                rr=mid;
            else
                ll=mid+1;
        }
        rp=rr-1;
        ans=max(ans,min(temp[i].dist2,getmax(1,0,num-1,lp,rp)));
    }
}
int main() {
    //freopen("data.in","r",stdin);
    int n;
    while(scanf("%d",&n)!=EOF) {
        for(int i=0;i<n;i++)
            scanf("%lf%lf",&po[i].x,&po[i].y);
        ans=0;
        for(int i=0;i<n;i++)
            solve(n,i);
        printf("%lf\n",sqrt(ans)/2.0);
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <bitset>
#include <algorithm>
using namespace std;
#define MAXN 3333
int N;
int X[MAXN],Y[MAXN];
vector<long long> Node;
bitset<MAXN> Bit[MAXN];
long long dis(int i,int j) { return (X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j]); }
int main()
{
    scanf("%d",&N);
    for(int n=0;n<N;++n)
        scanf("%d%d",X+n,Y+n);
    for(int i=0;i<N;++i)
        for(int j=i+1;j<N;++j)
            Node.push_back((dis(i,j)<<32)|(i<<16)|j);
    sort(Node.begin(),Node.end());
    while(!Node.empty())
    {
        int i=Node.back()&0x7f7f,j=(Node.back()>>16)&0x7f7f;
        Bit[i][j]=Bit[j][i]=true;
        if((Bit[i]&Bit[j])!=0)
            break;
        Node.pop_back();
    }
    printf("%.20lf\n",sqrt((double)(Node.back()>>32))/2);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <bitset>
#include <algorithm>
using namespace std;
#define MAXN 3333
int N;
int X[MAXN],Y[MAXN];
vector<long long> Node;
bitset<MAXN> Bit[MAXN];
long long dis(int i,int j) { return (X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j]); }
int main()
{
    scanf("%d",&N);
    for(int n=0;n<N;++n)
        scanf("%d%d",X+n,Y+n);
    for(int i=0;i<N;++i)
        for(int j=i+1;j<N;++j)
            Node.push_back((dis(i,j)<<32)|(i<<16)|j);
    sort(Node.begin(),Node.end());
    while(!Node.empty())
    {
        int i=Node.back()&0x3f3f,j=(Node.back()>>16)&0x3f3f;
        if((Bit[i]&Bit[j])!=0)
            break;
        Bit[i][j]=Bit[j][i]=true;
        Node.pop_back();
    }
    printf("%.20lf\n",sqrt((double)(Node.back()>>32))/2);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <bitset>
#include <algorithm>
#include <functional>
using namespace std;
#define MAXN 3333
int N,M;
int X[MAXN],Y[MAXN];
vector<long long> Node;
bitset<MAXN> Bit[MAXN];
long long dis(int i,int j) { return (X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j]); }
int main()
{
    scanf("%d",&N);
    for(int n=0;n<N;++n)
        scanf("%d%d",X+n,Y+n);
    for(int i=0;i<N;++i)
        for(int j=i+1;j<N;++j)
            Node.push_back((dis(i,j)<<32)|(i<<16)|j);
    sort(Node.begin(),Node.end(),greater<long long>());
    for(M=0;;++M)
    {
        int i=Node[M]&0x3f3f,j=(Node[M]>>16)&0x3f3f;
        Bit[i][j]=Bit[j][i]=true;
        if((Bit[i]&Bit[j])!=0)
            break;
    }
    printf("%.20lf\n",sqrt((double)(Node[M]>>32))/2);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <bitset>
#include <algorithm>
using namespace std;
#define MAXN 3333
int N;
int X[MAXN],Y[MAXN];
vector<long long> Node;
bitset<MAXN> Bit[MAXN];
long long dis(int i,int j) { return (X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j]); }
int main()
{
    scanf("%d",&N);
    for(int n=0;n<N;++n)
        scanf("%d%d",X+n,Y+n);
    for(int i=0;i<N;++i)
        for(int j=i+1;j<N;++j)
            Node.push_back((dis(i,j)<<32)|(i<<16)|j);
    sort(Node.begin(),Node.end());
    while(!Node.empty())
    {
        int i=Node.back()&0x3f3f,j=(Node.back()>>16)&0x3f3f;
        Bit[i][j]=Bit[j][i]=true;
        if((Bit[i]&Bit[j])!=0)
            break;
        Node.pop_back();
    }
    printf("%.20lf\n",sqrt((double)(Node.back()>>34)));
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <bitset>
#include <algorithm>
using namespace std;
#define MAXN 3333
int N;
int X[MAXN],Y[MAXN];
vector<long long> Node;
bitset<MAXN> Bit[MAXN];
long long dis(int i,int j) { return (X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j]); }
int main()
{
    scanf("%d",&N);
    for(int n=0;n<N;++n)
        scanf("%d%d",X+n,Y+n);
    for(int i=0;i<N;++i)
        for(int j=i+1;j<N;++j)
            Node.push_back((dis(i,j)<<32)|(i<<16)|j);
    sort(Node.begin(),Node.end());
    while(!Node.empty())
    {
        int i=Node.back()&0xffff,j=(Node.back()>>16)&0xffff;
        Bit[i][j]=Bit[j][i]=true;
        if((Bit[i]&Bit[j])!=0)
            break;
        Node.pop_back();
    }
    printf("%.20lf\n",sqrt((double)(Node.back()>>32))/2);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <bitset>
#include <algorithm>
using namespace std;
#define MAXN 3333
int N;
int X[MAXN],Y[MAXN];
vector<long long> Node;
bitset<MAXN> Bit[MAXN];
long long dis(int i,int j) { return (X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j]); }
int main()
{
    scanf("%d",&N);
    for(int n=0;n<N;++n)
        scanf("%d%d",X+n,Y+n);
    for(int i=0;i<N;++i)
        for(int j=i+1;j<N;++j)
            Node.push_back((dis(i,j)<<32)|(i<<16)|j);
    sort(Node.begin(),Node.end());
    while(!Node.empty())
    {
        int i=Node.back()&0x3f3f,j=(Node.back()>>16)&0x3f3f;
        Bit[i][j]=Bit[j][i]=true;
        if((Bit[i]&Bit[j])!=0)
            break;
        Node.pop_back();
    }
    printf("%.20lf\n",sqrt((double)(Node.back()>>32))/2);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <sstream>
#include <iostream>
#include <set>
#include <map>
#include <cassert>
#include <complex>

#define REP(AA,BB) for(int AA=0; AA<(BB); ++AA)
#define FOR(AA,BB,CC) for(int AA=(BB); AA<(CC); ++AA)
#define FC(AA,BB) for(__typeof((AA).begin()) BB=(AA).begin(); BB!=(AA).end(); ++BB)
#define SZ(AA) ((int)((AA).size()))
#define ALL(AA) (AA).begin(), (AA).end()
#define PB push_back
#define MP make_pair

using namespace std;

typedef vector<int> VI;
typedef pair<int, int> PII;
typedef long long LL;
typedef long double LD;

typedef complex<int> point;

#define X real()
#define Y imag()

const double EPS = 1e-9;

int operator^(const point &a, const point &b) {
    return a.X * b.Y - a.Y * b.X;
}

bool cmp_xy(const point &a, const point &b) {
    if (a.X == b.X) {
        return a.Y < b.Y;
    }
    return a.X < b.X;
}

void hull_pass(vector<point> &p, vector<point> &S) {
    FC (p, it) {
        while (SZ(S) >= 2 && ((S[SZ(S) - 1] - S[SZ(S) - 2]) ^ (*it - S[SZ(S) - 2])) >= 0) {
            S.pop_back();
        }
        S.PB(*it);
    }
    S.pop_back();
}

void hull(const vector<point> &poly, vector<point> &res) {
    if (SZ(poly) < 3) {
        res = poly;
        return;
    }
    vector<point> p = poly, S;
    //sort(ALL(p), cmp_xy);
    hull_pass(p, S);
    res = S; S.clear();
    reverse(ALL(p));
    hull_pass(p, S);
    res.insert(res.end(), ALL(S));
    reverse(ALL(res));
}

int farthest(const vector<point> &P) {
    if (P.empty()) {
        return 0;
    }
    int a = 0, b = 0, n = SZ(P);
    REP (i, n) {
        if (P[i].Y < P[a].Y || (P[i].Y == P[a].Y && P[i].X > P[a].X)) {
            a = i;
        }
        if (P[i].Y > P[b].Y || (P[i].Y == P[b].Y && P[i].X < P[b].X)) {
            b = i;
        }
    }
    int res = 0;
    REP (f, 2 * n + 5) {
        res = max(res, norm(P[a] - P[b]));
        int na = (a + 1) % n, nb = (b + 1) % n;
        LL cr = (P[b] - P[nb]) ^ (P[na] - P[a]);
        if (cr > 0) {
            b = nb;
        } else {
            a = na;
            if (cr == 0) {
                b = nb;
            }
        }
    }
    return res;
}

vector<point> P;

bool check(int D) {
    vector<point> tmp, ch; tmp.reserve(SZ(P));
    REP (i, SZ(P)) {
        tmp.clear();
        FOR (j, i + 1, SZ(P)) {
            if (norm(P[i] - P[j]) >= D) {
                tmp.PB(P[j]);
            }
        }
        hull(tmp, ch);
        if (farthest(ch) >= D) {
            return true;
        }
    }
    return false;
}

int main(void) {
    int n; scanf("%d", &n);
    P = vector<point>(n);
    REP (i, n) {
        int x, y; scanf("%d%d", &x, &y);
        P[i] = point(x, y);
    }
    sort(ALL(P), cmp_xy);
    int l = 0, r = 1000000000, best = 0;
    while (l <= r) {
        int mid = (l + r) / 2;
        if (check(mid)) {
            best = mid;
            l = mid + 1;
        } else {
            r = mid - 1;
        }
    }
    printf("%.20lf\n", 0.5 * sqrt(best));
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <sstream>
#include <iostream>
#include <set>
#include <map>
#include <cassert>
#include <bitset>
#include <cmath>

#define REP(AA,BB) for(int AA=0; AA<(BB); ++AA)
#define FOR(AA,BB,CC) for(int AA=(BB); AA<(CC); ++AA)
#define FC(AA,BB) for(__typeof((AA).begin()) BB=(AA).begin(); BB!=(AA).end(); ++BB)
#define SZ(AA) ((int)((AA).size()))
#define ALL(AA) (AA).begin(), (AA).end()
#define PB push_back
#define MP make_pair

using namespace std;

typedef vector<int> VI;
typedef pair<int, int> PII;
typedef long long LL;
typedef long double LD;

const int MAXN = 3000, SZ = (MAXN + 31) / 32; const unsigned int ONE = 1;

struct point {
    int x, y;
    point (int _x = 0, int _y = 0) : x(_x), y(_y) {}
    point operator-(const point &a) const {
        return point(x - a.x, y - a.y);
    }
    int mag() const {
        return x * x + y * y;
    }
};

point p[MAXN + 10];
int dist[MAXN + 10][MAXN + 10];

struct bits {
    unsigned int c[SZ];
    bits() { reset(); }
    void reset() {
        memset(c, 0, sizeof c);
    }
    void set(int k) {
        c[k >> 5] |= (ONE << (k & 31));
    }
    bool check(const bits &b) const {
        REP (i, SZ) {
            if (c[i] & b.c[i]) {
                return true;
            }
        }
        return false;
    }
};

bits b[MAXN + 10];

bool check(int n, int K) {
    REP (i, n) {
        b[i].reset();
        REP (j, n) {
            if (i != j && dist[i][j] >= K) {
                b[i].set(j);
            }
        }
        REP (j, i) {
            if (dist[i][j] >= K && b[i].check(b[j])) {
                return true;
            }
        }
    }
    return false;
}

int main(void) {
    int n; scanf("%d", &n);
    REP (i, n) {
        scanf("%d%d", &p[i].x, &p[i].y);
    }
    REP (i, n) {
        REP (j, n) {
            dist[i][j] = (p[i] - p[j]).mag();
        }
    }
    int l = 0, r = 1000000000, best = 0;
    while (l <= r) {
        int mid = (l + r) / 2;
        if (check(n, mid)) {
            best = mid;
            l = mid + 1;
        } else {
            r = mid - 1;
        }
    }
    printf("%.15lf\n", 0.5 * sqrt(0.0 + best));
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <sstream>
#include <iostream>
#include <set>
#include <map>
#include <cassert>
#include <complex>

#define REP(AA,BB) for(int AA=0; AA<(BB); ++AA)
#define FOR(AA,BB,CC) for(int AA=(BB); AA<(CC); ++AA)
#define FC(AA,BB) for(__typeof((AA).begin()) BB=(AA).begin(); BB!=(AA).end(); ++BB)
#define SZ(AA) ((int)((AA).size()))
#define ALL(AA) (AA).begin(), (AA).end()
#define PB push_back
#define MP make_pair

using namespace std;

typedef vector<int> VI;
typedef pair<int, int> PII;
typedef long long LL;
typedef long double LD;

typedef complex<int> point;

#define X real()
#define Y imag()

const double EPS = 1e-9;

int operator^(const point &a, const point &b) {
    return a.X * b.Y - a.Y * b.X;
}

bool cmp_xy(const point &a, const point &b) {
    if (a.X == b.X) {
        return a.Y < b.Y;
    }
    return a.X < b.X;
}

void hull_pass(vector<point> &p, vector<point> &S) {
    FC (p, it) {
        while (SZ(S) >= 2 && ((S[SZ(S) - 1] - S[SZ(S) - 2]) ^ (*it - S[SZ(S) - 2])) >= 0) {
            S.pop_back();
        }
        S.PB(*it);
    }
}

void hull(const vector<point> &poly, vector<point> &res) {
    if (SZ(poly) < 3) {
        res = poly;
        return;
    }
    vector<point> p = poly, S;
    //sort(ALL(p), cmp_xy);
    hull_pass(p, S);
    res = S; S.clear();
    reverse(ALL(p));
    hull_pass(p, S);
    res.insert(res.end(), ALL(S));
    reverse(ALL(res));
}

int farthest(const vector<point> &P) {
    if (P.empty()) {
        return 0;
    }
    int a = 0, b = 0, n = SZ(P);
    REP (i, n) {
        if (P[i].Y < P[a].Y || (P[i].Y == P[a].Y && P[i].X > P[a].X)) {
            a = i;
        }
        if (P[i].Y > P[b].Y || (P[i].Y == P[b].Y && P[i].X < P[b].X)) {
            b = i;
        }
    }
    int res = 0;
    REP (f, 2 * n + 5) {
        res = max(res, norm(P[a] - P[b]));
        int na = (a + 1) % n, nb = (b + 1) % n;
        LL cr = (P[b] - P[nb]) ^ (P[na] - P[a]);
        if (cr > 0) {
            b = nb;
        } else {
            a = na;
            if (cr == 0) {
                b = nb;
            }
        }
    }
    return res;
}

vector<point> P;

bool check(int D) {
    vector<point> tmp, ch; tmp.reserve(SZ(P));
    REP (i, SZ(P)) {
        tmp.clear();
        FOR (j, i + 1, SZ(P)) {
            if (norm(P[i] - P[j]) >= D) {
                tmp.PB(P[j]);
            }
        }
        hull(tmp, ch);
        if (farthest(ch) >= D) {
            return true;
        }
    }
    return false;
}

int main(void) {
    int n; scanf("%d", &n);
    P = vector<point>(n);
    REP (i, n) {
        int x, y; scanf("%d%d", &x, &y);
        P[i] = point(x, y);
    }
    sort(ALL(P), cmp_xy);
    int l = 0, r = 1000000000, best = 0;
    while (l <= r) {
        int mid = (l + r) / 2;
        if (check(mid)) {
            best = mid;
            l = mid + 1;
        } else {
            r = mid - 1;
        }
    }
    printf("%.20lf\n", 0.5 * sqrt(best));
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <sstream>
#include <iostream>
#include <set>
#include <map>
#include <cassert>
#include <bitset>
#include <cmath>
#include <ctime>

#define REP(AA,BB) for(int AA=0; AA<(BB); ++AA)
#define FOR(AA,BB,CC) for(int AA=(BB); AA<(CC); ++AA)
#define FC(AA,BB) for(__typeof((AA).begin()) BB=(AA).begin(); BB!=(AA).end(); ++BB)
#define SZ(AA) ((int)((AA).size()))
#define ALL(AA) (AA).begin(), (AA).end()
#define PB push_back
#define MP make_pair

using namespace std;

typedef vector<int> VI;
typedef pair<int, int> PII;
typedef long long LL;
typedef long double LD;

const int MAXN = 3000, SZ = (MAXN + 31) / 32; const unsigned int ONE = 1;

struct point {
    int x, y;
    point (int _x = 0, int _y = 0) : x(_x), y(_y) {}
    point operator-(const point &a) const {
        return point(x - a.x, y - a.y);
    }
    int mag() const {
        return x * x + y * y;
    }
};

point p[MAXN + 10];
int dist[MAXN + 10][MAXN + 10];

struct bits {
    unsigned int c[SZ];
    bits() { reset(); }
    void reset() {
        memset(c, 0, sizeof c);
    }
    void set(int k) {
        c[k >> 5] |= (ONE << (k & 31));
    }
    bool check(const bits &b) const {
        REP (i, SZ) {
            if (c[i] & b.c[i]) {
                return true;
            }
        }
        return false;
    }
};

bits b[MAXN + 10];

bool check(int n, int K) {
    REP (i, n) {
        b[i].reset();
        REP (j, n) {
            if (i != j && dist[i][j] >= K) {
                b[i].set(j);
            }
        }
        REP (j, i) {
            if (dist[i][j] >= K && b[i].check(b[j])) {
                return true;
            }
        }
    }
    return false;
}

int main(void) {
    int n; scanf("%d", &n);
    REP (i, n) {
        scanf("%d%d", &p[i].x, &p[i].y);
    }
    srand(time(NULL)); random_shuffle(p, p + n);
    REP (i, n) {
        REP (j, n) {
            dist[i][j] = (p[i] - p[j]).mag();
        }
    }
    int l = 0, r = 1000000000, best = 0;
    while (l <= r) {
        int mid = (l + r) / 2;
        if (check(n, mid)) {
            best = mid;
            l = mid + 1;
        } else {
            r = mid - 1;
        }
    }
    printf("%.15lf\n", 0.5 * sqrt(0.0 + best));
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <sstream>
#include <iostream>
#include <set>
#include <map>
#include <cassert>
#include <bitset>
#include <cmath>

#define REP(AA,BB) for(int AA=0; AA<(BB); ++AA)
#define FOR(AA,BB,CC) for(int AA=(BB); AA<(CC); ++AA)
#define FC(AA,BB) for(__typeof((AA).begin()) BB=(AA).begin(); BB!=(AA).end(); ++BB)
#define SZ(AA) ((int)((AA).size()))
#define ALL(AA) (AA).begin(), (AA).end()
#define PB push_back
#define MP make_pair

using namespace std;

typedef vector<int> VI;
typedef pair<int, int> PII;
typedef long long LL;
typedef long double LD;

const int MAXN = 3000, SZ = (MAXN + 31) / 32; const unsigned int ONE = 1;

struct point {
    int x, y;
    point (int _x = 0, int _y = 0) : x(_x), y(_y) {}
    point operator-(const point &a) const {
        return point(x - a.x, y - a.y);
    }
    int mag() const {
        return x * x + y * y;
    }
};

point p[MAXN + 10];
int dist[MAXN + 10][MAXN + 10];

struct bits {
    unsigned int c[SZ];
    bits() { reset(); }
    void reset() {
        memset(c, 0, sizeof c);
    }
    void set(int k) {
        c[k >> 5] |= (ONE << (k & 31));
    }
    bool check(const bits &b) const {
        REP (i, SZ) {
            if (c[i] & b.c[i]) {
                return true;
            }
        }
        return false;
    }
};

bits b[MAXN + 10];

bool check(int n, int K) {
    REP (i, n) {
        b[i].reset();
        REP (j, n) {
            if (i != j && dist[i][j] >= K) {
                b[i].set(j);
            }
        }
        REP (j, i) {
            if (dist[i][j] >= K && b[i].check(b[j])) {
                return true;
            }
        }
    }
    return false;
}

int main(void) {
    int n; scanf("%d", &n);
    REP (i, n) {
        scanf("%d%d", &p[i].x, &p[i].y);
    }
    srand(time(NULL)); random_shuffle(p, p + n);
    REP (i, n) {
        REP (j, n) {
            dist[i][j] = (p[i] - p[j]).mag();
        }
    }
    int l = 0, r = 1000000000, best = 0;
    while (l <= r) {
        int mid = (l + r) / 2;
        if (check(n, mid)) {
            best = mid;
            l = mid + 1;
        } else {
            r = mid - 1;
        }
    }
    printf("%.15lf\n", 0.5 * sqrt(0.0 + best));
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <sstream>
#include <iostream>
#include <set>
#include <map>
#include <cassert>
#include <complex>

#define REP(AA,BB) for(int AA=0; AA<(BB); ++AA)
#define FOR(AA,BB,CC) for(int AA=(BB); AA<(CC); ++AA)
#define FC(AA,BB) for(__typeof((AA).begin()) BB=(AA).begin(); BB!=(AA).end(); ++BB)
#define SZ(AA) ((int)((AA).size()))
#define ALL(AA) (AA).begin(), (AA).end()
#define PB push_back
#define MP make_pair

using namespace std;

typedef vector<int> VI;
typedef pair<int, int> PII;
typedef long long LL;
typedef long double LD;

typedef complex<int> point;

#define X real()
#define Y imag()

const double EPS = 1e-9;

int operator^(const point &a, const point &b) {
    return a.X * b.Y - a.Y * b.X;
}

bool cmp_xy(const point &a, const point &b) {
    if (a.X == b.X) {
        return a.Y < b.Y;
    }
    return a.X < b.X;
}

void hull_pass(vector<point> &p, vector<point> &S) {
    FC (p, it) {
        while (SZ(S) >= 2 && ((S[SZ(S) - 1] - S[SZ(S) - 2]) ^ (*it - S[SZ(S) - 2])) >= 0) {
            S.pop_back();
        }
        S.PB(*it);
    }
    S.pop_back();
}

void hull(const vector<point> &poly, vector<point> &res) {
    if (SZ(poly) < 3) {
        res = poly;
        return;
    }
    vector<point> p = poly, S;
    //sort(ALL(p), cmp_xy);
    hull_pass(p, S);
    res = S; S.clear();
    reverse(ALL(p));
    hull_pass(p, S);
    res.insert(res.end(), ALL(S));
    reverse(ALL(res));
}

int farthest(const vector<point> &P) {
    if (P.empty()) {
        return 0;
    }
    int a = 0, b = 0, n = SZ(P);
    REP (i, n) {
        if (P[i].Y < P[a].Y || (P[i].Y == P[a].Y && P[i].X > P[a].X)) {
            a = i;
        }
        if (P[i].Y > P[b].Y || (P[i].Y == P[b].Y && P[i].X < P[b].X)) {
            b = i;
        }
    }
    int res = 0;
    REP (f, n + 10) {
        res = max(res, norm(P[a] - P[b]));
        int na = (a + 1) % n, nb = (b + 1) % n;
        LL cr = (P[b] - P[nb]) ^ (P[na] - P[a]);
        if (cr > 0) {
            b = nb;
        } else {
            a = na;
            if (cr == 0) {
                b = nb;
            }
        }
    }
    return res;
}

vector<point> P;

bool check(int D) {
    vector<point> tmp, ch; tmp.reserve(SZ(P));
    REP (i, SZ(P)) {
        tmp.clear();
        FOR (j, i + 1, SZ(P)) {
            if (norm(P[i] - P[j]) >= D) {
                tmp.PB(P[j]);
            }
        }
        hull(tmp, ch);
        if (farthest(ch) >= D) {
            return true;
        }
    }
    return false;
}

int main(void) {
    int n; scanf("%d", &n);
    P = vector<point>(n);
    REP (i, n) {
        int x, y; scanf("%d%d", &x, &y);
        P[i] = point(x, y);
    }
    sort(ALL(P), cmp_xy);
    int l = 0, r = 1000000000, best = 0;
    while (l <= r) {
        int mid = (l + r) / 2;
        if (check(mid)) {
            best = mid;
            l = mid + 1;
        } else {
            r = mid - 1;
        }
    }
    printf("%.20lf\n", 0.5 * sqrt(best));
    return 0;
}


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <math.h>
#include <queue>

using namespace std;

const double EPS=1E-8;
inline int SG(double x){
    if(x>-EPS&&x<EPS) return 0;
    return x>0?1:-1;
}

class PT{
    public:
        double x,y;
        PT(){}
        PT(double _x,double _y){
            x=_x; y=_y;
        }
        PT operator-(const PT& p) const{
            return PT(x-p.x,y-p.y);
        }
        PT operator+(const PT& p) const{
            return PT(x+p.x,y+p.y);
        }
        bool operator<(const PT& p) const{
            if(SG(x-p.x)==0) return SG(y-p.y)<0;
            return x<p.x;
        }
        double len2(){
            return x*x+y*y;
        }
        double operator^(const PT& p) const{
            return x*p.y-y*p.x;
        }
        double dis2to(const PT& p) const{
            double dx=x-p.x;
            double dy=y-p.y;
            return dx*dx+dy*dy;
        }
};
PT pt[3010];
PT qt[3010];
int u[3010];

inline double tri(const PT& p1,const PT& p2,const PT& p3){
    return (p2-p1)^(p3-p1);
}

int main(){
    int n,i,j,k,tt,r,z,p,q,f,flag,l,s;
    double L,R,M,M2,d;
    scanf("%d",&n);
    for( i=0; i<n; i++ ){
        scanf("%lf %lf",&pt[i].x,&pt[i].y);
    }
    sort(pt,pt+n);
    L=0;
    R=100000;
    for( tt=0; tt<50; tt++ ){
        M=(L+R)/2;
        M2=M*M*4;
        flag=0;
        for( i=0; i<n; i++ ){
            r=-1;
            f=0;
            for( j=0; j<n; j++ ){
                if(pt[j].dis2to(pt[i])<M2){
                    u[j]=1;
                    continue;
                }else{
                    f++;
                    u[j]=0;
                    l=j;
                }
                while(r>0 && tri(qt[r-1],qt[r],pt[j])<EPS) r--;
                qt[++r]=pt[j];
            }
            if(f<=1) continue;
            z=r;
            for( j=l-1; j>=0; j-- ){
                if(u[j]) continue;
                while(r>z && tri(qt[r-1],qt[r],pt[j])<EPS) r--;
                qt[++r]=pt[j];
            }
            if(r==2){
                if(qt[0].dis2to(qt[1])>=M2){
                    flag=1;
                    break;
                }
            }else{
                p=1;
                q=0;
                f=0;
                for( j=1; j<r; j++ ){
                    if(tri(qt[0],qt[1],qt[j])>tri(qt[0],qt[1],qt[q])) q=j;
                }
                s=0;
                while(s<r+10){
                    d=qt[p].dis2to(qt[q]);
                    if(d>=M2){
                        flag=1;
                        goto out;
                    }
                    if(f){
                        if(((qt[q+1]-qt[q])^(qt[p+1]-qt[p]))>0){
                            f=0;
                            p=(p+1)%r;
                            s++;
                        }else{
                            q=(q+1)%r;
                        }
                    }else{
                        if(((qt[p+1]-qt[p])^(qt[q+1]-qt[q]))>0){
                            f=1;
                            q=(q+1)%r;
                        }else{
                            p=(p+1)%r;
                            s++;
                        }
                    }
                }
            }
        }
out:
        if(flag){
            L=M;
        }else{
            R=M;
        }
    }
    printf("%.12f\n",L);
    return 0;
}


#include <stdio.h>
int t, n;
long long a[5000];

int main(){
    scanf("%d", &t);
    while(t--){
        scanf("%d", &n);
        long long second_number = 0;
        for(long long i = 0; i < n; i++){
            scanf("%lld", &a[i]);
            if(a[0] != a[i]){
                second_number = i;
            }
        }
        if(second_number == 0)
            printf("NO\n");
        else{
            printf("YES\n");
            for(long long i = 1; i < n; i++){
                if(a[0] == a[i])
                    printf("%lld %lld\n", second_number + 1, i + 1);
                else
                    printf("%d %lld\n", 1, i + 1);
            }
        }
    }
    return 0;
}


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>

typedef struct
{
    int val;
    int ind;
}cell;

void sort(cell *A, int N)
{
    int sorted , temp_val,temp_ind , i;

    sorted=0;
    while (!sorted)
    {
        sorted=1;
        for(i=0;i<N-1;i++)
        {
            if(A[i].val>A[i+1].val)
            {
                sorted=0;
                temp_val=A[i].val; temp_ind=A[i].ind;
                A[i].val=A[i+1].val; A[i].ind=A[i+1].ind;
                A[i+1].val=temp_val; A[i+1].ind=temp_ind;
            }
        }
    }
}

int main()
{

    int T,N,i,j,rept;

    scanf("%d",&T);

    while(T>0)
    {
        scanf("%d" , &N);
        cell A[N];

        for(i=0 ; i<N ; i++)
        {
            scanf("%d",&A[i].val);
            A[i].ind=i+1;
        }
        rept=1;
        for(i=1;i<N;i++)
        {
            if(!(A[i].val==A[i-1].val)) rept=0;
        }
        if(rept) printf("NO\n");
        else
        {
            printf("YES\n");
            sort(A,N);

            i=1;
            while( A[i].val==A[i-1].val) i++;
            for(j=i ; j< N ; j++)
            {
                printf("%d %d\n",A[0].ind,A[j].ind);
            }
            for(j=1 ; j<i ; j++)
            {
                printf("%d %d\n",A[j].ind,A[i].ind);
            }
        }

        T--;

    }

    return 0;
}


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>

typedef struct
{
    int val;
    int ind;
}cell;

void sort(cell *A, int N)
{
    int sorted , temp_val,temp_ind , i;

    sorted=0;
    while (!sorted)
    {
        sorted=1;
        for(i=0;i<N-1;i++)
        {
            if(A[i].val>A[i+1].val)
            {
                sorted=0;
                temp_val=A[i].val; temp_ind=A[i].ind;
                A[i].val=A[i+1].val; A[i].ind=A[i+1].ind;
                A[i+1].val=temp_val; A[i+1].ind=temp_ind;
            }
        }
    }
}

int main()
{

    int T,N,i,j,sum;

    scanf("%d",&T);

    while(T>0)
    {
        scanf("%d" , &N);
        cell A[N];
        sum=0;
        for(i=0 ; i<N ; i++)
        {
            scanf("%d",&A[i].val);
            A[i].ind=i+1;
            sum+=A[i].val;
        }
        if(sum==A[0].val*N) printf("NO\n");
        else
        {
            printf("YES\n");
            sort(A,N);

            i=1;
            while( A[i].val==A[i-1].val) i++;
            for(j=i ; j< N ; j++)
            {
                printf("%d %d\n",A[0].ind,A[j].ind);
            }
            for(j=1 ; j<i ; j++)
            {
                printf("%d %d\n",A[j].ind,A[i].ind);
            }
        }

        T--;

    }

    return 0;
}


#include<stdio.h>

void solve() {
	int n, same = 1, max = 0;
	scanf("%d", &n);
	int a[n + 1];
	for (int i = 0; i < n; i++) {
		scanf("%d", &a[i]);
		if (i >= 1) {
			if (a[i] == a[0]) {
				same++;
			}
		}
	}

	if (same == n) printf("NO\n");
	else {
		printf("YES\n");
		for (int i = 1; i < n; i++) {
			if (a[i] == 0)continue;
			else {
				for (int k = 0; k < n; k++) {
					if (a[i] == a[k]) continue;
					else {
						printf("%d %d\n", i + 1, k + 1);
						break;
					}
				}
			}
		}
	}
}

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		solve();
	}
	return 0;
}


#include <stdio.h>

int main(void) {
	int t;
	scanf("%d",&t);
	while(t--)
	{
	    int n,v,c,x;v=0;c=0;
	    int pi,pj;pi=0;pj=0;
	    scanf("%d",&n);
	    int a[n];
	    x=n-1;
	    for(int i=0;i<n;i++)
	    {
	      scanf("%d",&a[i]);
	    }
	    for(int i=1;i<n;i++)
	    {
	      if(a[i]!=a[i-1])
	      {
	          v=1;
	          break;
	      }
	    }
	    if(v==1)
	    {
	        printf("YES\n");
	        for(int i=0;i<n;i++)
	        {
	            for(int j=i;j<n;j++)
	            {
	                if(a[i]!=a[j])
	                {
	                    c=c+1;
	                    pi=i+1;
	                    pj=j+1;
	                    printf("%d %d\n",pi,pj);
	                }
	                if(c==x)
	                {
	                    break;
	                }
	            }
	            if(c==x)
	                {
	                    break;
	                }
	        }
	    }
	    else{
	        printf("NO\n");
	    }
	}
	return 0;
}


#include <stdio.h>

int main(void) {
	int t;
	scanf("%d",&t);
	while(t--)
	{
	    int n,v,c,x;v=0;c=0;
	    scanf("%d",&n);
	    int a[n];
	    x=n-1;
	    for(int i=0;i<n;i++)
	    {
	      scanf("%d",&a[i]);
	    }
	    for(int i=1;i<n;i++)
	    {
	      if(a[i]!=a[i-1])
	      {
	          v=1;
	          break;
	      }
	    }
	    if(v==1)
	    {
	        printf("YES\n");
	        for(int i=0;i<n;i++)
	        {
	            for(int j=i;j<n;j++)
	            {
	                if(a[i]!=a[j])
	                {
	                    c=c+1;
	                    printf("%d %d\n",i+1,j+1);
	                }
	                if(c==x)
	                {
	                    break;
	                }
	            }
	            if(c==x)
	                {
	                    break;
	                }
	        }
	    }
	    else{
	        printf("NO\n");
	    }
	}
	return 0;
}


#include <stdio.h>

int main(void) {
	int t;
	scanf("%d",&t);
	while(t--)
	{
	    int n,v,c,x;v=0;c=0;
	    scanf("%d",&n);
	    int a[n];
	    x=n-1;
	    for(int i=0;i<n;i++)
	    {
	      scanf("%d",&a[i]);
	    }
	    for(int i=1;i<n;i++)
	    {
	      if(a[i]!=a[i-1])
	      {
	          v=1;
	          break;
	      }
	    }
	    if(v==1)
	    {
	        printf("YES\n");
	        for(int i=0;i<n;i++)
	        {
	            for(int j=i;j<n;j++)
	            {
	                if(a[i]!=a[j])
	                {
	                    c=c+1;
	                    printf("%d %d\n",a[i],a[j]);
	                }
	                if(c==x)
	                {
	                    break;
	                }
	            }
	            if(c==x)
	                {
	                    break;
	                }
	        }
	    }
	    else{
	        printf("NO\n");
	    }
	}
	return 0;
}


#include <stdio.h>

int main(void) {
	int t;
	scanf("%d",&t);
	while(t--)
	{
	    int n,pm,v,c,x;v=0;c=0;
	    int pi,pj;pi=0;pj=0;
	    scanf("%d",&n);
	    int a[n];
	    x=n-1;
	    for(int i=0;i<n;i++)
	    {
	      scanf("%d",&a[i]);
	    }
	    for(int i=1;i<n;i++)
	    {
	      if(a[i]!=a[i-1])
	      {
	          v=1;
	          break;
	      }
	    }
	    if(v==1)
	    {
	        printf("YES\n");
	            for(int j=1;j<n;j++)
	            {
	                if(a[0]!=a[j])
	                {
	                    c=c+1;
	                    pi=1;
	                    pj=j+1;
	                    pm=pj;
	                    printf("%d %d\n",pi,pj);
	                }
	            }
	            for(int j=1;j<n;j++)
	            {
	                if(c==x)
	                {
	                    break;
	                }
	                if(a[j]==a[0])
	                {
	                    c=c+1;
	                    pj=j+1;
	                    printf("%d %d\n",pj,pm);
	                }
	            }
	    }
	    else{
	        printf("NO\n");
	    }
	}
	return 0;
}


#include <stdio.h>

int main(){
	int t;
	scanf("%d", &t);
	while(t--){
		int n, yes=0, a, b;
		scanf("%d", &n);
		int p[n];
		for(int i=0; i<n; ++i){
			scanf("%d", &p[i]);
			if(i>0 && p[i]!=p[i-1]){
				yes=i;
				a=p[i-1];
				b=p[i];
			}
		}
		if(yes==0){
			printf("NO\n");
		}
		else{
			printf("YES\n");
			printf("%d %d\n", yes, yes+1);
			for(int i=0; i<n; ++i){
				if(i!=yes-1 && i!=yes){
					if(p[i]==a){
						printf("%d %d\n", yes+1, i+1);
					}
					else{
						printf("%d %d\n", yes, i+1);
					}
				}
			}
		}
	}
	return 0;
}


#include<stdio.h>

int a[5001];
int vis[5001];
int p1[5001];
int p2[5002];

int main(){
	int t,n;
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);

		for(int i=0;i<n;i++) {
			vis[i]=0;
			scanf("%d",&a[i]);
		}

		int k = 0;
		int cu = 0;
		int found = 1;

		while(k<n&&found){
			vis[cu]=1;
			found=0;
			for(int ne = 0;ne<n;ne++){

				if(a[cu]!=a[ne]&&!vis[ne]){

					p1[k]=cu;
					p2[k]=ne;
					k++;
					cu=ne;
					found=1;
					break;
				}
			}
		}

		if(k==n-1){
			printf("YES\n");
			for(int i=0;i<k;i++) printf("%d %d\n",p1[i]+1,p2[i]+1);
		}
		else printf("NO\n");
	}
}


#include<stdio.h>

int a[5001];
int vis[5001];
int p[5001];
int noVis=0;

int dfs(int n,int s){
	vis[s]=1;
	noVis++;
	if(noVis==n){
		printf("YES\n");
		for(int i=1;i<n;i++) printf("%d %d\n",p[i]+1,i+1);
		return 1;
	}

	for(int i=0;i<n;i++){
		if(a[i]!=a[s]&&!vis[i]){
			p[i]=s;
			if(dfs(n,i)) return 1;
		}
	}
	return 0;
}

int main(){
	int t,n;
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		for(int i=0;i<n;i++) {
			vis[i]=0;
			scanf("%d",&a[i]);
		}
		noVis=0;
		if(!dfs(n,0)) printf("NO\n");
	}

	return 0;
}


#include <stdio.h>

int main()
{
    int t,n,a[5005];
    scanf("%d",&t);
    while(t--)
    {
        int flag=1,b;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        for(int i=1;i<n;i++)
        {
            if(a[i]!=a[i-1])
                flag=0;
        }
        if(flag)
        {
            printf("NO\n");
        }
        else
        {
            printf("YES\n");
            for(int i=1;i<n;i++)
            {
                if(a[i]!=a[0])
                {
                    printf("1 %d\n",i+1);
                    b=i;
                }
            }
            for(int i=1;i<n;i++)
            {
                if(a[i]==a[0])
                    printf("%d %d\n",b+1,i+1);
            }
        }
    }
    return 0;
}


#include <stdio.h>

int main()
{
    int t,n,a[5005];
    scanf("%d",&t);
    while(t--)
    {
        int flag=1,b;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        for(int i=1;i<n;i++)
        {
            if(a[i]!=a[i-1])
                flag=0;
        }
        if(flag)
        {
            printf("NO\n");
        }
        else
        {
            printf("YES\n");
            for(int i=1;i<n;i++)
            {
                if(a[i]!=a[0])
                    printf("1 %d\n",i+1);
                b=i;
            }
            for(int i=1;i<n;i++)
            {
                if(a[i]==a[0])
                    printf("%d %d\n",b+1,i+1);
            }
        }
    }
    return 0;
}


#include <stdio.h>
#include <stdlib.h>
typedef long long ll;
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define max(l,r) ((l)>(r)?(l):(r))
#define min(l,r) ((l)<(r)?(l):(r))
#define chmax(l,r) (l=max(l,(r)))
#define chmin(l,r) (l=min(l,(r)))
const ll MOD = 1000000007;
const int INF = (1 << 30);      // > 10^9

/////merge sort(Pair)
typedef struct{int first, second;} P;
P tpar[202020];
void msortp(P *ar, int l, int r){ // [l,r)
    if(r-l<=1) return;
    int mid=(l+r)/2;
    if(r-mid>1) msortp(ar,mid,r);
    if(mid-l>1) msortp(ar,l,mid);
    for(int li=l,ri=mid,afi=l;afi<r;afi++){
        if(ri>=r||(li<mid&&ri<r&&( (ar[li].first<ar[ri].first) || //cmp(<:up >:down)
           ((ar[li].first==ar[ri].first) && (ar[li].second<=ar[ri].second) ))))
            tpar[afi]=ar[li++]; //cmp
        else
            tpar[afi]=ar[ri++];
    }
    for(int i=l;i<r;i++) ar[i]=tpar[i];
}
/////

int a[202020];
P p[202020];

int main(){
    int t; scanf("%d", &t);
    while(t--){
        int n; scanf("%d", &n);
        rep(i,n) scanf("%d", &p[i].first);
        rep(i,n) p[i].second = i+1;
        msortp(p, 0, n);

        if(p[0].first == p[n-1].first){
            puts("NO");
            continue;
        }
        puts("YES");
        rep(i,n-2){
            if(p[i+1].first == p[0].first){
                printf("%d %d\n", p[i+1].second, p[n-1].second);
            }else{
                printf("%d %d\n", p[i+1].second, p[0].second);
            }
        }
        printf("%d %d\n", p[n-1].second, p[0].second);
    }
}


#include<stdio.h>
#include<stdio.h>
int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {int n,j,d=0,ind;scanf("%d",&n);long long int a[n],m;
        for(j=0;j<n;j++)scanf("%lld",(a+j));
        m=a[0];
        for(j=0;j<n;j++)
        {
            if(m==a[j])
            {
                d++;
            }
            else{ind=j+1;}
        }
        if(d==n)
        {
            printf("NO\n");continue;
        }
        int dis[d],k=0,that[n-d];
        //printf("->%d\n",d);
        for(j=0;k<d;j++)
        {
            if(a[j]==a[0])
            {
                dis[k++]=j+1;
            }
        }
        k=0;
        for(j=0;k<(n-d);j++)
        {
            if(a[j]!=a[0])
            {
              //  printf("j->%d\n",j+1);
                that[k++]=j+1;
            }
        }
        printf("YES\n");
        for(j=0;j<n-d;j++)
        {
            printf("1 %d\n",that[j]);
        }
        if(d>1)
        for(j=1;j<d;j++)
        {
            printf("%d %d\n",dis[j],ind);
        }
    }
    return 0;
}


'use strict'; /*jslint node:true, browser:true, es6:true*/
const rl = require('readline').createInterface({ input: process.stdin, output: process.stdout })
const print = console.log
const lines = []
rl.on('line', line => {
    lines.push(line);
});
rl.on('close', main)
let rli = 0;
function readline() {
    return lines[rli++];
}

function query(arr){
    let set = new Set(arr);
    if (set.size==1)
        return print('NO');
    print('YES');
    let left = [], last;
    for (let i=1; i<arr.length; i++)
    {
        if (arr[0]==arr[i])
            left.push(i);
        else
        {
            print('1 '+(i+1));
            last = i;
        }
    }
    for (let i=0; i<left.length; i++)
        print((last+1)+' '+(left[i]+1));

}

function main() {
    var q = +readline();
    while (q--)
    {
        var n = +readline();
        let arr = readline().split(' ').map(a=>+a);
        query(arr);
    }
}


const readline = require('readline').createInterface({
  input: process.stdin,
  output: process.stdout
});

let lineNum = 0;
let countOfData = null;
let data = [];
readline.on('line', line => {
  lineNum++;
  if(lineNum === 1) {
    countOfData = +line * 2;
    return;
  }

  data.push(line);

  if(lineNum - 1 === countOfData) {
    goToSolution(data);
  }

});

function goToSolution(data) {
  data.forEach((districts, i) => {
    if(i % 2 !== 0) {

      districts = districts.split(' ');
      const map = districts.reduce((acc, band, i) => {
        (band in acc) ?
          acc[band].push(i + 1) :
          acc[band] = [i + 1];
        return acc;
      }, {});

      const bands = Object.keys(map);
      if(bands.length > 1) {
        console.log('YES');
        for(let i = 0; i < bands.length; i++) {
          if(bands.length - 1 !== i) console.log(`${map[bands[i]][0]} ${map[bands[i + 1]][0]}`);

          if(i > 0) {
            for(let j = 1; j < map[bands[i - 1]].length; j++) {
              console.log(`${map[bands[i]][0]} ${map[bands[i - 1]][j]}`)
            }
          }

          if(bands.length - 1 === i) {
            for(let j = 1; j < map[bands[i]].length; j++) {
              console.log(`${map[bands[i - 1]][map[bands[i - 1]].length - 1]} ${map[bands[i]][j]}`)
            }
          }

        }
      } else {
        console.log('NO');
      }
    }
  })
}


let inputString = "";
let currentLine = 0;
process.stdin.on("data", (data) => {
  inputString += data;
});
process.stdin.on("end", function () {
  inputString = inputString
    .trim()
    .split("\n")
    .map((str) => str.trim());
  main();
});
function readLine() {
  return inputString[currentLine++];
}

// utils
const MOD = 1e9 + 7;
const mod = (n) => ((n % MOD) + MOD) % MOD;
const add = (a, b) => mod(mod(a) + mod(b));
const sub = (a, b) => mod(mod(a) - mod(b));
function mul() {
  for (var a = arguments, r = a[0], i = a.length; --i; )
    r = ((((r >> 16) * a[i]) % MOD) * 65536 + (r & 65535) * a[i]) % MOD;
  return r;
}
function inv(b) {
  for (var a = MOD, u = 0, v = 1, t; b; v = t)
    (t = (a / b) | 0), (a -= t * b), (u -= t * v), (t = a), (a = b), (b = t), (t = u), (u = v);
  u %= MOD;
  return u < 0 ? u + MOD : u;
}
function pow(base, n) {
  if (n === 0) return 1;
  let p = pow(base, Math.floor(n / 2));
  let res = mul(mod(p), mod(p));
  if (n % 2 === 1) res = mul(mod(res), base);
  return res;
}
function highestOneBit(i) {
  i |= i >> 1;
  i |= i >> 2;
  i |= i >> 4;
  i |= i >> 8;
  i |= i >> 16;
  return i - (i >>> 1);
}
function permutation(arr, len, store = "", permutations = []) {
  if (store.length === len) {
    permutations.push(store);
    return;
  }
  for (let i = 0; i < arr.length; i++) {
    const newArr = [...arr];
    const newChar = newArr.splice(i, 1);
    permutation(newArr, len, store.concat(newChar), permutations);
  }
  return permutations;
}

function main() {
  let t = +readLine();
  while (t--) {
    const len = +readLine();
    const arr = readLine().split(" ").map(Number);
    const map = new Map();

    for (let i = 0; i < len; i++) {
      const num = arr[i];
      if (map.has(num)) {
        map.set(num, [...map.get(num), i + 1]);
      } else {
        map.set(num, [i + 1]);
      }
    }

    if (map.size === 1) console.log("NO");
    else {
      console.log("YES");
      const values = [...map.values()];
      const [firstRow, secondRow] = [values[0], values[1]];
      for (let row = 1; row < values.length; row++) {
        for (let col = 0; col < values[row].length; col++) {
          console.log(`${firstRow[0]} ${values[row][col]}`);
        }
      }
      for (let col = 1; col < firstRow.length; col++) {
        console.log(`${secondRow[0]} ${firstRow[col]}`);
      }
    }
  }
}


//Don't have to see. start------------------------------------------
var read = require('readline').createInterface({
	input: process.stdin, output: process.stdout
});
var obj; var inLine = [];
read.on('line', function(input){inLine.push(input);});
read.on('close', function(){
	obj = init(inLine);
	console.error('\n↑入力 ↓出力');
	Main();
});
function makeClone(obj){return (obj instanceof Set) ? new Set(Array.from(obj)) : JSON.parse(JSON.stringify(obj));}
function nextInt(){return myconv(next(),1);} function nextStrArray(){return myconv(next(),2);}
function nextIntArray(){return myconv(next(),4);} function nextCharArray(){return myconv(next(),6);}
function next(){return obj.next();} function hasNext(){return obj.hasNext();}
function init(input){
	return {
		list : input, index : 0, max : input.length,
		hasNext : function(){return (this.index < this.max);},
		next : function(){if(this.hasNext()){return this.list[this.index++];}else{throw 'ArrayIndexOutOfBoundsException ‚There is no more input';}}
	};
}
function myout(s){console.log(s);}
function myerr(s){console.error('debug:' + require('util').inspect(s,false,null));}
//param "no" is
//unknown or outlier : return i. 1: parseInt.
//2: split space. 4: split space and parseInt.
//6: split 1 character. 7: split 1 character and parseInt.
//8: join space. 9: join nextline. 0: join no character.
function myconv(i,no){try{switch(no){case 1:return parseInt(i);case 2:return i.split(' ');case 4:return i.split(' ').map(Number);case 6:return i.split('');case 7:return i.split('').map(Number);case 8:return i.join(' ');case 9:return i.join('\n');case 0:return i.join('');default:return i;}}catch(e){return i;}}

//Don't have to see. end------------------------------------------
function Main(){
	var t = nextInt();
	var output = [];
	for(var i = 0; i < t; i++){
		var N = nextInt();
		var tmp = nextIntArray();
		var isOK = false;
		var list = new Array(N);
		var uf = unionFind(N);
		for(var j = 0; j < N; j++){
			list[j] = {
				no : j,
				G : tmp[j],
				child : new Set()
			}
		}
		var connect = new Set();
		for(var j = 0; j < N - 1; j++){
			for(var k = j + 1; k < N; k++){
				if(list[j].child.has(list[k].no) || list[k].child.has(list[j].no)){
					continue;
				}
				if(list[j].G != list[k].G && !uf.isSame(j, k)){
					isOK = true;
					list[j].child.add(list[k].no);
					list[k].child.add(list[j].no);
					connect.add((j + 1) + ":" + (k + 1));
					uf.doUnion(j, k);
				}
			}
		}
		if(isOK){
			output.push("YES");
			var keys = Array.from(connect);
			for(var j = 0; j < keys.length; j++){
				output.push(keys[j].split(":").join(" "));
			}
		}else{
			output.push("NO");
		}
	}
	myout(myconv(output, 9));
}
function unionFind(n){
  var uf = {
    //全てのインデックスは「-X(親、絶対値はグループの大きさ)」「自分が属する親(≒根)」のいずれかを持つ。
    //最初はみんなグループの大きさ1の親
    "list" : new Array(n).fill(-1),

    //同じ親を持つか
    "isSame" : function(mae, ato){
      return this.getRootIndex(mae) == this.getRootIndex(ato);
    },
    //自身の親インデックスをたどって根っこに着く
    //親にたどり終えたら子に帰っていくついでに、子たちに「共通の親を持っている」ことを知らせる
    "getRootIndex" : function(index){
      if(this.list[index] < 0){
        return index;
      }else{
        this.list[index] = this.getRootIndex(this.list[index]);
        return this.list[index];
      }
    },
    //異なる親同士のまとまりを一つにする（同じ親ならスルー）
    //小さいグループの親が大きいグループの親の直下に着く
    //グループの大きさも更新する
    "doUnion" : function(mae, ato){
      var maeRoot = this.getRootIndex(mae);
      var atoRoot = this.getRootIndex(ato);
      if(!this.isSame(maeRoot, atoRoot)){
        if(maeRoot >= atoRoot){
          this.list[maeRoot] += this.list[atoRoot];
          this.list[atoRoot] = maeRoot;
        }else{
          this.list[atoRoot] += this.list[maeRoot];
          this.list[maeRoot] = atoRoot;
        }
      }
    },
    //「-X(親、絶対値はグループの大きさ)」
    //なので、インデックスを指定→親を知る→親の持つグループの大きさがわかる。
    //ただしマイナス値なので、掛け算して返す。
    "getSize" : function(index){
      return -this.list[this.getRootIndex(index)];
    }
  }
  return uf;
}


//Don't have to see. start------------------------------------------
var read = require('readline').createInterface({
	input: process.stdin, output: process.stdout
});
var obj; var inLine = [];
read.on('line', function(input){inLine.push(input);});
read.on('close', function(){
	obj = init(inLine);
	console.error('\n↑入力 ↓出力');
	Main();
});
function makeClone(obj){return (obj instanceof Set) ? new Set(Array.from(obj)) : JSON.parse(JSON.stringify(obj));}
function nextInt(){return myconv(next(),1);} function nextStrArray(){return myconv(next(),2);}
function nextIntArray(){return myconv(next(),4);} function nextCharArray(){return myconv(next(),6);}
function next(){return obj.next();} function hasNext(){return obj.hasNext();}
function init(input){
	return {
		list : input, index : 0, max : input.length,
		hasNext : function(){return (this.index < this.max);},
		next : function(){if(this.hasNext()){return this.list[this.index++];}else{throw 'ArrayIndexOutOfBoundsException ‚There is no more input';}}
	};
}
function myout(s){console.log(s);}
function myerr(s){console.error('debug:' + require('util').inspect(s,false,null));}
//param "no" is
//unknown or outlier : return i. 1: parseInt.
//2: split space. 4: split space and parseInt.
//6: split 1 character. 7: split 1 character and parseInt.
//8: join space. 9: join nextline. 0: join no character.
function myconv(i,no){try{switch(no){case 1:return parseInt(i);case 2:return i.split(' ');case 4:return i.split(' ').map(Number);case 6:return i.split('');case 7:return i.split('').map(Number);case 8:return i.join(' ');case 9:return i.join('\n');case 0:return i.join('');default:return i;}}catch(e){return i;}}

//Don't have to see. end------------------------------------------
function Main(){
	var t = nextInt();
	var output = [];
	for(var i = 0; i < t; i++){
		var N = nextInt();
		var tmp = nextIntArray();
		var isOK = false;
		var list = new Array(N);
		for(var j = 0; j < N; j++){
			list[j] = {
				no : j,
				G : tmp[j],
				child : new Set()
			}
		}
		var connect = 0;
		for(var j = 0; j < N - 1; j++){
			if(connect == N - 1){
				break;
			}
			for(var k = j + 1; k < N; k++){
				if(list[j].child.has(list[k].no) || list[k].child.has(list[j].no)){
					continue;
				}
				if(list[j].G != list[k].G){
					isOK = true;
					list[j].child.add(list[k].no);
					connect++;
					if(connect == N - 1){
						break;
					}
					//list[k].child.add(list[j].no);
				}
			}
		}
		if(isOK){
			output.push("YES");
			for(var j = 0; j < N; j++){
				var keys = Array.from(list[j].child);
				for(var k = 0; k < keys.length; k++){
					output.push((j + 1) + " " + (keys[k] + 1));
				}
			}
		}else{
			output.push("NO");
		}
	}
	myout(myconv(output, 9));
}


process.stdin.resume();
process.stdin.setEncoding('utf-8');

let stdinInput = '';

process.stdin.on('data', input => {
  stdinInput += input;
})

process.stdin.on('end', () => {
  main(stdinInput);
})

function main(data) {
    data = data.split('\n');
    const testCases = data[0] * 2;
    let i = 1;
    while (i <= testCases) {
      // let a = data[i].trim();
      // const n = data[i] * 1;
      // const k = a[1];
      const s = data[i + 1].trim().split(' ').map(Number);
      // s.sort((a, b) => b - a);
      let idx = 0;
      let max = 0;
      let obj = {};

      for (let j = 0; j < s.length; j += 1) {
        if (obj[s[j]]) obj[s[j]].push(j);
        else obj[s[j]] = [j];
        // if (s[j] > max) {
        //   max = s[j];
        //   idx = j;
        // }
      }

      let arr = Object.values(obj);
      // console.log(arr);

      if (arr.length < 2) console.log('NO');
      else {
        console.log('YES');
        for (let j = 1; j < arr.length; j += 1) {
          for (let k = 0; k < arr[j].length; k += 1) {
            console.log(arr[0][0] + 1 + ' ' + (arr[j][k] + 1));
          }
        }
        for (let j = 1; j < arr[0].length; j += 1) {
          console.log(arr[1][0] + 1 + ' ' + (arr[0][j] + 1));
        }
      }

      i += 2;
    }
}


process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
    inputString += inputStdin;
});

process.stdin.on('end', _ => {
    inputString = inputString.trim().split('\n').map(string => {
        return string.trim();
    });

    districtConnections();
});

function readline() {
    return inputString[currentLine++];
}

function pi(a) {
    return parseInt(a);
}

function ti(a){
    for(let i = 0; i < a.length; i++)
        a[i] = pi(a[i]);

    return a;
}

function districtConnections(){
    let t = pi(readline());
    while(t > 0){
        t--;
        let n = pi(readline());
        let a = ti(readline().split(' '));

        let count = 0;
        let map = new Array(1000000005);
        let x = [];
        for(let i = 0; i < n; i++){
            if(map[a[i]] === undefined){
                count++;
                map[a[i]] = i+1;
                x.push(a[i]);
            }

            if(count >= 2)
                break;
        }

        if(count < 2){
            console.log('NO');
            continue;
        }

        console.log('YES');
        for(let i = 1; i < n; i++){
            if(a[i-1] !== x[0]){
                console.log(i, map[x[0]]);
            }else{
                console.log(i, map[x[1]]);
            }
        }
    }
}


process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
    inputString += inputStdin;
});

process.stdin.on('end', _ => {
    inputString = inputString.trim().split('\n').map(string => {
        return string.trim();
    });

    districtConnections();
});

function readline() {
    return inputString[currentLine++];
}

function pi(a) {
    return parseInt(a);
}

function ti(a){
    for(let i = 0; i < a.length; i++)
        a[i] = pi(a[i]);

    return a;
}

function districtConnections(){
    let t = pi(readline());
    while(t > 0){
        t--;
        let n = pi(readline());
        let a = ti(readline().split(' '));

        let count = 0;
        let map = new Array(1000000005);
        let x = [];
        for(let i = 0; i < n; i++){
            if(map[a[i]] === undefined){
                count++;
                map[a[i]] = i+1;
                x.push(a[i]);
            }

            if(count >= 2)
                break;
        }

        if(count < 2){
            console.log('NO');
            continue;
        }

        console.log('YES');
        let visited = new Array(n+1);

        for(let i = 1; i <= n; i++){
            if(a[i-1] !== x[0]){
                if(!(visited[i] && visited[map[x[0]]])){
                    console.log(i, map[x[0]]);
                    visited[i] = true;
                    visited[map[x[0]]] = true;
                }
            }else{
                if(!(visited[i] && visited[map[x[1]]])){
                    console.log(i, map[x[1]]);
                    visited[i] = true;
                    visited[map[x[1]]] = true;
                }
            }
        }
    }
}


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using CompLib.Util;
using System.Threading;
using CompLib.DataStructure;

public class Program
{
    public void Solve()
    {
        var sc = new Scanner();
        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) {AutoFlush = false});
        int t = sc.NextInt();
        for (int i = 0; i < t; i++)
        {
            Q(sc);
        }

        Console.Out.Flush();
    }

    void Q(Scanner sc)
    {
        int n = sc.NextInt();
        int[] a = sc.IntArray();

        var e = new List<(int f, int t)>();
        var uf = new UnionFind(n);
        for (int i = 0; e.Count < n - 1 && i < n; i++)
        {
            for (int j = i + 1; e.Count < n - 1 && j < n; j++)
            {
                if (a[i] == a[j]) continue;
                if (uf.Connect(i, j))
                {
                    e.Add((i, j));
                }
            }
        }

        if (e.Count < n - 1)
        {
            Console.WriteLine("NO");
            return;
        }

        Console.WriteLine("YES");
        foreach ((int f, int t) in e)
        {
            Console.WriteLine($"{f + 1} {t + 1}");
        }
    }

    public static void Main(string[] args) => new Program().Solve();
    // public static void Main(string[] args) => new Thread(new Program().Solve, 1 << 27).Start();
}

namespace CompLib.DataStructure
{
    using System.Collections.Generic;
    using System.Linq;

    class UnionFind
    {
        private readonly int _n;
        private readonly int[] _parent, _size;

        /// <summary>
        /// n頂点の無向グラフに 1.辺を追加, 2.2頂点が同じ連結成分に属するか判定 ができるデータ構造
        /// </summary>
        /// <param name="n">頂点の個数</param>
        public UnionFind(int n)
        {
            _n = n;
            _parent = new int[_n];
            _size = new int[_n];
            for (int i = 0; i < _n; i++)
            {
                _parent[i] = i;
                _size[i] = 1;
            }
        }

        /// <summary>
        /// iがいる連結成分の代表値
        /// </summary>
        /// <param name="i"></param>
        /// <returns></returns>
        public int Find(int i) => _parent[i] == i ? i : Find(_parent[i]);

        /// <summary>
        /// x,yが同じ連結成分にいるか?
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public bool Same(int x, int y) => Find(x) == Find(y);

        /// <summary>
        /// (x, y)に辺を追加する
        /// </summary>
        /// <remarks>
        /// ACLでは連結された代表値を返しますが、ここでは連結できたか?を返します
        /// </remarks>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns>x,yが違う連結成分だったならtrueを返す</returns>
        public bool Connect(int x, int y)
        {
            x = Find(x);
            y = Find(y);
            if (x == y) return false;

            // データ構造をマージする一般的なテク
            if (_size[x] > _size[y])
            {
                _parent[y] = x;
                _size[x] += _size[y];
            }
            else
            {
                _parent[x] = y;
                _size[y] += _size[x];
            }

            return true;
        }

        /// <summary>
        /// iが含まれる成分のサイズ
        /// </summary>
        /// <param name="i"></param>
        /// <returns></returns>
        public int GetSize(int i) => _size[Find(i)];

        /// <summary>
        /// 連結成分のリスト
        /// </summary>
        /// <returns></returns>
        public List<int>[] Groups()
        {
            var leaderBuf = new int[_n];
            var groupSize = new int[_n];
            for (int i = 0; i < _n; i++)
            {
                leaderBuf[i] = Find(i);
                groupSize[leaderBuf[i]]++;
            }

            var result = new List<int>[_n];
            for (int i = 0; i < _n; i++)
            {
                result[i] = new List<int>(groupSize[i]);
            }

            for (int i = 0; i < _n; i++)
            {
                result[leaderBuf[i]].Add(i);
            }

            return result.Where(ls => ls.Count > 0).ToArray();
        }
    }
}

namespace CompLib.Util
{
    using System;
    using System.Linq;

    class Scanner
    {
        private string[] _line;
        private int _index;
        private const char Separator = ' ';

        public Scanner()
        {
            _line = new string[0];
            _index = 0;
        }

        public string Next()
        {
            if (_index >= _line.Length)
            {
                string s;
                do
                {
                    s = Console.ReadLine();
                } while (s.Length == 0);

                _line = s.Split(Separator);
                _index = 0;
            }

            return _line[_index++];
        }

        public string ReadLine()
        {
            _index = _line.Length;
            return Console.ReadLine();
        }

        public int NextInt() => int.Parse(Next());
        public long NextLong() => long.Parse(Next());
        public double NextDouble() => double.Parse(Next());
        public decimal NextDecimal() => decimal.Parse(Next());
        public char NextChar() => Next()[0];
        public char[] NextCharArray() => Next().ToCharArray();

        public string[] Array()
        {
            string s = Console.ReadLine();
            _line = s.Length == 0 ? new string[0] : s.Split(Separator);
            _index = _line.Length;
            return _line;
        }

        public int[] IntArray() => Array().Select(int.Parse).ToArray();
        public long[] LongArray() => Array().Select(long.Parse).ToArray();
        public double[] DoubleArray() => Array().Select(double.Parse).ToArray();
        public decimal[] DecimalArray() => Array().Select(decimal.Parse).ToArray();
    }
}


using System;
using System.Collections.Generic;
using System.Linq;

namespace TaskCS
{
    class Program
    {
        static void Main(string[] args)
        {
            var t = int.Parse(Console.ReadLine());
            var textAnswers = new string[t];
            var valueAnswers = new List<List<string>>();

            for (var test = 0; test < t; test++)
            {
                var n = int.Parse(Console.ReadLine());
                var sectors = Console.ReadLine().Split().Select(e => int.Parse(e)).ToArray();
                var baseGang = sectors[0];
                var startRoad = 1;
                var roads = new List<string>();

                for (var i = 0; i < n; i++)
                    if (sectors[i] != baseGang)
                        roads.Add($"{startRoad} {i + 1}");

                if (roads.Count != 0)
                {
                    textAnswers[test] = "YES";
                    var endRoad = roads[0].Split()[1];
                    for (var i = 1; i < n; i++)
                        if (sectors[i] == baseGang)
                            roads.Add($"{i + 1} {endRoad}");
                }
                else
                    textAnswers[test] = "NO";
                valueAnswers.Add(roads);
            }

            for (var i = 0; i < t; i++)
            {
                Console.WriteLine(textAnswers[i]);
                if (valueAnswers[i].Count != 0)
                    foreach (var e in valueAnswers[i])
                        Console.WriteLine(e);
            }
        }
    }
}


using System;
using System.IO;
using System.Text;

namespace Districts_Connection
{
    internal class Program
    {
        private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024*10), Encoding.ASCII, false, 1024*10);
        private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024*10), Encoding.ASCII, 1024*10);

        private static void Main(string[] args)
        {
            int t = Next();
            for (int i = 0; i < t; i++)
            {
                Solve();
            }
            writer.Flush();
        }

        private static void Solve()
        {
            int n = Next();

            var nn = new int[n];
            for (int i = 0; i < n; i++)
            {
                nn[i] = Next();
            }

            for (int i = 1; i < n; i++)
            {
                if (nn[i] != nn[i - 1])
                {
                    writer.WriteLine("YES");
                    writer.Write(i);
                    writer.Write(' ');
                    writer.WriteLine(i + 1);

                    for (int j = i + 1; j < n; j++)
                    {
                        if (nn[j] == nn[i])
                        {
                            writer.Write(i);
                            writer.Write(' ');
                            writer.WriteLine(j + 1);
                        }
                        else
                        {
                            writer.Write(i + 1);
                            writer.Write(' ');
                            writer.WriteLine(j + 1);
                        }
                    }
                    for (int j = i - 2; j >= 0; j--)
                    {
                        if (nn[j] == nn[i])
                        {
                            writer.Write(i);
                            writer.Write(' ');
                            writer.WriteLine(j + 1);
                        }
                        else
                        {
                            writer.Write(i + 1);
                            writer.Write(' ');
                            writer.WriteLine(j + 1);
                        }
                    }

                    return;
                }
            }
            writer.WriteLine("NO");
        }

        private static int Next()
        {
            int c;
            int res = 0;
            do
            {
                c = reader.Read();
                if (c == -1)
                    return res;
            } while (c < '0' || c > '9');
            res = c - '0';
            while (true)
            {
                c = reader.Read();
                if (c < '0' || c > '9')
                    return res;
                res *= 10;
                res += c - '0';
            }
        }
    }
}


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;

public static class Ex
{
    public static bool IsNullOrEmpty(this string s) { return string.IsNullOrEmpty(s); }
    public static void yesno(this bool b) => Console.WriteLine(b ? "yes" : "no");
    public static void YesNo(this bool b) => Console.WriteLine(b ? "Yes" : "No");
    public static void YESNO(this bool b) => Console.WriteLine(b ? "YES" : "NO");
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    //public static bool Chmax<T>(ref this T a, T b) where T : struct, IComparable<T>
    //{
    //    if (b.CompareTo(a) > 0) { a = b; return true; }
    //    else return false;
    //}
    //[MethodImpl(MethodImplOptions.AggressiveInlining)]
    //public static bool Chmin<T>(ref this T a, T b) where T : struct, IComparable<T>
    //{
    //    if (b.CompareTo(a) < 0) { a = b; return true; }
    //    else return false;
    //}

    public static List<string> FastSort(this List<string> s) { s.Sort(StringComparer.OrdinalIgnoreCase); return s.ToList(); }

    public static int PopCount(this uint bits)
    {
        bits = (bits & 0x55555555) + (bits >> 1 & 0x55555555);
        bits = (bits & 0x33333333) + (bits >> 2 & 0x33333333);
        bits = (bits & 0x0f0f0f0f) + (bits >> 4 & 0x0f0f0f0f);
        bits = (bits & 0x00ff00ff) + (bits >> 8 & 0x00ff00ff);
        return (int)((bits & 0x0000ffff) + (bits >> 16 & 0x0000ffff));
    }
}

partial class Program
{
    string GetStr() { return Console.ReadLine().Trim(); }
    char GetChar() { return Console.ReadLine().Trim()[0]; }
    int GetInt() { return int.Parse(Console.ReadLine().Trim()); }
    long GetLong() { return long.Parse(Console.ReadLine().Trim()); }
    double GetDouble() { return double.Parse(Console.ReadLine().Trim()); }
    string[] GetStrArray() { return Console.ReadLine().Trim().Split(' '); }
    string[][] GetStrArray(int N)
    {
        var res = new string[N][];
        for (int i = 0; i < N; i++) res[i] = Console.ReadLine().Trim().Split(' ');
        return res;
    }
    int[] GetIntArray() { return Console.ReadLine().Trim().Split(' ').Select(int.Parse).ToArray(); }
    int[][] GetIntArray(int N)
    {
        var res = new int[N][];
        for (int i = 0; i < N; i++) res[i] = Console.ReadLine().Trim().Split(' ').Select(int.Parse).ToArray();
        return res;
    }
    public long[] GetLongArray() { return Console.ReadLine().Trim().Split(' ').Select(long.Parse).ToArray(); }
    long[][] GetLongArray(int N)
    {
        var res = new long[N][];
        for (int i = 0; i < N; i++) res[i] = Console.ReadLine().Trim().Split(' ').Select(long.Parse).ToArray();
        return res;
    }
    char[] GetCharArray() { return Console.ReadLine().Trim().Split(' ').Select(char.Parse).ToArray(); }
    double[] GetDoubleArray() { return Console.ReadLine().Trim().Split(' ').Select(double.Parse).ToArray(); }
    double[][] GetDoubleArray(int N)
    {
        var res = new double[N][];
        for (int i = 0; i < N; i++) res[i] = Console.ReadLine().Trim().Split(' ').Select(double.Parse).ToArray();
        return res;
    }
    char[][] GetGrid(int H)
    {
        var res = new char[H][];
        for (int i = 0; i < H; i++) res[i] = Console.ReadLine().Trim().ToCharArray();
        return res;
    }
    T[] CreateArray<T>(int N, T value)
    {
        var res = new T[N];
        for (int i = 0; i < N; i++) res[i] = value;
        return res;
    }
    T[][] CreateArray<T>(int H, int W, T value)
    {
        var res = new T[H][];
        for (int i = 0; i < H; i++)
        {
            res[i] = new T[W];
            for (int j = 0; j < W; j++) res[i][j] = value;
        }
        return res;
    }
    T[][][] CreateArray<T>(int H, int W, int R, T value)
    {
        var res = new T[H][][];
        for (int i = 0; i < H; i++)
        {
            res[i] = new T[W][];
            for (int j = 0; j < W; j++)
            {
                res[i][j] = new T[R];
                for (int k = 0; k < R; k++) res[i][j][k] = value;
            }
        }
        return res;
    }

    Dictionary<int, List<int>> GetUnweightedAdjacencyList(int N, int M, bool isDirected, bool isNode_0indexed)
    {
        var dic = new Dictionary<int, List<int>>();
        foreach (var e in Enumerable.Range(0, N)) { dic.Add(e, new List<int>()); }
        for (int i = 0; i < M; i++)
        {
            var input = GetIntArray();
            var a = isNode_0indexed ? input[0] : input[0] - 1;
            var b = isNode_0indexed ? input[1] : input[1] - 1;
            dic[a].Add(b);
            if (isDirected == false) dic[b].Add(a);
        }
        return dic;
    }
    //Dictionary<int, List<(int node, long cost)>> GetWeightedAdjacencyList(int N, int M, bool isDirected, bool isNode_0indexed)
    //{
    //    var dic = new Dictionary<int, List<(int, long)>>();
    //    foreach (var e in Enumerable.Range(0, N)) { dic.Add(e, new List<(int, long)>()); }
    //    for (int i = 0; i < M; i++)
    //    {
    //        var input = GetIntArray();
    //        var a = isNode_0indexed ? input[0] : input[0] - 1;
    //        var b = isNode_0indexed ? input[1] : input[1] - 1;
    //        var c = input[2];
    //        dic[a].Add((b, c));
    //        if (isDirected == false) dic[b].Add((a, c));
    //    }
    //    return dic;
    //}

    bool eq<T, U>() => typeof(T).Equals(typeof(U));
    T ct<T, U>(U a) => (T)Convert.ChangeType(a, typeof(T));
    T cv<T>(string s) => eq<T, int>() ? ct<T, int>(int.Parse(s))
                       : eq<T, long>() ? ct<T, long>(long.Parse(s))
                       : eq<T, double>() ? ct<T, double>(double.Parse(s))
                       : eq<T, char>() ? ct<T, char>(s[0])
                                         : ct<T, string>(s);
    void Multi<T>(out T a) => a = cv<T>(GetStr());
    void Multi<T, U>(out T a, out U b)
    {
        var ar = GetStrArray(); a = cv<T>(ar[0]); b = cv<U>(ar[1]);
    }
    void Multi<T, U, V>(out T a, out U b, out V c)
    {
        var ar = GetStrArray(); a = cv<T>(ar[0]); b = cv<U>(ar[1]); c = cv<V>(ar[2]);
    }
    void Multi<T, U, V, W>(out T a, out U b, out V c, out W d)
    {
        var ar = GetStrArray(); a = cv<T>(ar[0]); b = cv<U>(ar[1]); c = cv<V>(ar[2]); d = cv<W>(ar[3]);
    }
    void Multi<T, U, V, W, X>(out T a, out U b, out V c, out W d, out X e)
    {
        var ar = GetStrArray(); a = cv<T>(ar[0]); b = cv<U>(ar[1]); c = cv<V>(ar[2]); d = cv<W>(ar[3]); e = cv<X>(ar[4]);
    }
    void Multi<T, U, V, W, X, Y>(out T a, out U b, out V c, out W d, out X e, out Y f)
    {
        var ar = GetStrArray(); a = cv<T>(ar[0]); b = cv<U>(ar[1]); c = cv<V>(ar[2]); d = cv<W>(ar[3]); e = cv<X>(ar[4]); f = cv<Y>(ar[5]);
    }

    void Output<T>(T t) => Console.WriteLine(t);
    void Output<T>(IList<T> ls) => Console.WriteLine(string.Join(" ", ls));
    void Debug<T>(IList<IList<T>> ls)
    {
        foreach (var l in ls)
            foreach (var s in l)
                Console.WriteLine(s);
    }

    void Swap<T>(ref T a, ref T b) { T temp = a; a = b; b = temp; }

    int[] dx = new int[] { 1, 0, -1, 0, 1, -1, -1, 1 };
    int[] dy = new int[] { 0, 1, 0, -1, 1, 1, -1, -1 };
    long mod = 1000000007;
}

partial class Program
{
    static void Main()
    {
        Console.SetIn(new StreamReader(Console.OpenStandardInput(8192)));
        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
        new Program().Solve();
        Console.Out.Flush();
        Console.Read();
    }

    public void Solve()
    {
        int T = GetInt();
        for (int i = 0; i < T; i++)
        {
            SolveSolve();
        }
    }

    void SolveSolve()
    {
        int N = GetInt();
        var A = GetIntArray();
        var dict = new Dictionary<int, HashSet<int>>();
        for (int i = 0; i < N; i++) dict.Add(i, new HashSet<int>());
        for (int i = 0; i < N; i++)
        {
            for (int j = i + 1; j < N; j++)
            {
                if (A[i] != A[j])
                {
                    dict[i].Add(j);
                    dict[j].Add(i);
                }
            }
        }

        var from = new int[N].Select(e => -1).ToArray();
        var queue = new Queue<int>();
        queue.Enqueue(0);
        while (queue.Count() > 0)
        {
            var now = queue.Dequeue();
            foreach (var next in dict[now])
            {
                if (from[next] != -1) continue;
                from[next] = now;
                queue.Enqueue(next);
            }
        }

        if (from.Count(e => e == -1) > 1)
        {
            Output("NO");
            return;
        }
        Output("YES");
        for (int i = 1; i < N; i++)
        {
            Console.Write(i + 1);
            Console.Write(' ');
            Console.WriteLine(from[i] + 1);
        }

    }
}


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;

public static class Ex
{
    public static bool IsNullOrEmpty(this string s) { return string.IsNullOrEmpty(s); }
    public static void yesno(this bool b) => Console.WriteLine(b ? "yes" : "no");
    public static void YesNo(this bool b) => Console.WriteLine(b ? "Yes" : "No");
    public static void YESNO(this bool b) => Console.WriteLine(b ? "YES" : "NO");
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    //public static bool Chmax<T>(ref this T a, T b) where T : struct, IComparable<T>
    //{
    //    if (b.CompareTo(a) > 0) { a = b; return true; }
    //    else return false;
    //}
    //[MethodImpl(MethodImplOptions.AggressiveInlining)]
    //public static bool Chmin<T>(ref this T a, T b) where T : struct, IComparable<T>
    //{
    //    if (b.CompareTo(a) < 0) { a = b; return true; }
    //    else return false;
    //}

    public static List<string> FastSort(this List<string> s) { s.Sort(StringComparer.OrdinalIgnoreCase); return s.ToList(); }

    public static int PopCount(this uint bits)
    {
        bits = (bits & 0x55555555) + (bits >> 1 & 0x55555555);
        bits = (bits & 0x33333333) + (bits >> 2 & 0x33333333);
        bits = (bits & 0x0f0f0f0f) + (bits >> 4 & 0x0f0f0f0f);
        bits = (bits & 0x00ff00ff) + (bits >> 8 & 0x00ff00ff);
        return (int)((bits & 0x0000ffff) + (bits >> 16 & 0x0000ffff));
    }
}

partial class Program
{
    string GetStr() { return Console.ReadLine().Trim(); }
    char GetChar() { return Console.ReadLine().Trim()[0]; }
    int GetInt() { return int.Parse(Console.ReadLine().Trim()); }
    long GetLong() { return long.Parse(Console.ReadLine().Trim()); }
    double GetDouble() { return double.Parse(Console.ReadLine().Trim()); }
    string[] GetStrArray() { return Console.ReadLine().Trim().Split(' '); }
    string[][] GetStrArray(int N)
    {
        var res = new string[N][];
        for (int i = 0; i < N; i++) res[i] = Console.ReadLine().Trim().Split(' ');
        return res;
    }
    int[] GetIntArray() { return Console.ReadLine().Trim().Split(' ').Select(int.Parse).ToArray(); }
    int[][] GetIntArray(int N)
    {
        var res = new int[N][];
        for (int i = 0; i < N; i++) res[i] = Console.ReadLine().Trim().Split(' ').Select(int.Parse).ToArray();
        return res;
    }
    public long[] GetLongArray() { return Console.ReadLine().Trim().Split(' ').Select(long.Parse).ToArray(); }
    long[][] GetLongArray(int N)
    {
        var res = new long[N][];
        for (int i = 0; i < N; i++) res[i] = Console.ReadLine().Trim().Split(' ').Select(long.Parse).ToArray();
        return res;
    }
    char[] GetCharArray() { return Console.ReadLine().Trim().Split(' ').Select(char.Parse).ToArray(); }
    double[] GetDoubleArray() { return Console.ReadLine().Trim().Split(' ').Select(double.Parse).ToArray(); }
    double[][] GetDoubleArray(int N)
    {
        var res = new double[N][];
        for (int i = 0; i < N; i++) res[i] = Console.ReadLine().Trim().Split(' ').Select(double.Parse).ToArray();
        return res;
    }
    char[][] GetGrid(int H)
    {
        var res = new char[H][];
        for (int i = 0; i < H; i++) res[i] = Console.ReadLine().Trim().ToCharArray();
        return res;
    }
    T[] CreateArray<T>(int N, T value)
    {
        var res = new T[N];
        for (int i = 0; i < N; i++) res[i] = value;
        return res;
    }
    T[][] CreateArray<T>(int H, int W, T value)
    {
        var res = new T[H][];
        for (int i = 0; i < H; i++)
        {
            res[i] = new T[W];
            for (int j = 0; j < W; j++) res[i][j] = value;
        }
        return res;
    }
    T[][][] CreateArray<T>(int H, int W, int R, T value)
    {
        var res = new T[H][][];
        for (int i = 0; i < H; i++)
        {
            res[i] = new T[W][];
            for (int j = 0; j < W; j++)
            {
                res[i][j] = new T[R];
                for (int k = 0; k < R; k++) res[i][j][k] = value;
            }
        }
        return res;
    }

    Dictionary<int, List<int>> GetUnweightedAdjacencyList(int N, int M, bool isDirected, bool isNode_0indexed)
    {
        var dic = new Dictionary<int, List<int>>();
        foreach (var e in Enumerable.Range(0, N)) { dic.Add(e, new List<int>()); }
        for (int i = 0; i < M; i++)
        {
            var input = GetIntArray();
            var a = isNode_0indexed ? input[0] : input[0] - 1;
            var b = isNode_0indexed ? input[1] : input[1] - 1;
            dic[a].Add(b);
            if (isDirected == false) dic[b].Add(a);
        }
        return dic;
    }
    //Dictionary<int, List<(int node, long cost)>> GetWeightedAdjacencyList(int N, int M, bool isDirected, bool isNode_0indexed)
    //{
    //    var dic = new Dictionary<int, List<(int, long)>>();
    //    foreach (var e in Enumerable.Range(0, N)) { dic.Add(e, new List<(int, long)>()); }
    //    for (int i = 0; i < M; i++)
    //    {
    //        var input = GetIntArray();
    //        var a = isNode_0indexed ? input[0] : input[0] - 1;
    //        var b = isNode_0indexed ? input[1] : input[1] - 1;
    //        var c = input[2];
    //        dic[a].Add((b, c));
    //        if (isDirected == false) dic[b].Add((a, c));
    //    }
    //    return dic;
    //}

    bool eq<T, U>() => typeof(T).Equals(typeof(U));
    T ct<T, U>(U a) => (T)Convert.ChangeType(a, typeof(T));
    T cv<T>(string s) => eq<T, int>() ? ct<T, int>(int.Parse(s))
                       : eq<T, long>() ? ct<T, long>(long.Parse(s))
                       : eq<T, double>() ? ct<T, double>(double.Parse(s))
                       : eq<T, char>() ? ct<T, char>(s[0])
                                         : ct<T, string>(s);
    void Multi<T>(out T a) => a = cv<T>(GetStr());
    void Multi<T, U>(out T a, out U b)
    {
        var ar = GetStrArray(); a = cv<T>(ar[0]); b = cv<U>(ar[1]);
    }
    void Multi<T, U, V>(out T a, out U b, out V c)
    {
        var ar = GetStrArray(); a = cv<T>(ar[0]); b = cv<U>(ar[1]); c = cv<V>(ar[2]);
    }
    void Multi<T, U, V, W>(out T a, out U b, out V c, out W d)
    {
        var ar = GetStrArray(); a = cv<T>(ar[0]); b = cv<U>(ar[1]); c = cv<V>(ar[2]); d = cv<W>(ar[3]);
    }
    void Multi<T, U, V, W, X>(out T a, out U b, out V c, out W d, out X e)
    {
        var ar = GetStrArray(); a = cv<T>(ar[0]); b = cv<U>(ar[1]); c = cv<V>(ar[2]); d = cv<W>(ar[3]); e = cv<X>(ar[4]);
    }
    void Multi<T, U, V, W, X, Y>(out T a, out U b, out V c, out W d, out X e, out Y f)
    {
        var ar = GetStrArray(); a = cv<T>(ar[0]); b = cv<U>(ar[1]); c = cv<V>(ar[2]); d = cv<W>(ar[3]); e = cv<X>(ar[4]); f = cv<Y>(ar[5]);
    }

    void Output<T>(T t) => Console.WriteLine(t);
    void Output<T>(IList<T> ls) => Console.WriteLine(string.Join(" ", ls));
    void Debug<T>(IList<IList<T>> ls)
    {
        foreach (var l in ls)
            foreach (var s in l)
                Console.WriteLine(s);
    }

    void Swap<T>(ref T a, ref T b) { T temp = a; a = b; b = temp; }

    int[] dx = new int[] { 1, 0, -1, 0, 1, -1, -1, 1 };
    int[] dy = new int[] { 0, 1, 0, -1, 1, 1, -1, -1 };
    long mod = 1000000007;
}

partial class Program
{
    static void Main()
    {
        Console.SetIn(new StreamReader(Console.OpenStandardInput(8192)));
        //Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
        new Program().Solve();
        //Console.Out.Flush();
        Console.Read();
    }

    public void Solve()
    {
        int T = GetInt();
        for(int i = 0; i < T; i++)
        {
            SolveSolve();
        }
    }

    void SolveSolve()
    {
        int N = GetInt();
        var A = GetIntArray();
        var dict = new Dictionary<int, HashSet<int>>();
        for (int i = 0; i < N; i++) dict.Add(i, new HashSet<int>());
        for (int i = 0; i < N; i++)
        {
            for (int j = i + 1; j < N; j++)
            {
                if (A[i] != A[j])
                {
                    dict[i].Add(j);
                    dict[j].Add(i);
                }
            }
        }

        var from = new int[N].Select(e => -1).ToArray();
        var queue = new Queue<int>();
        queue.Enqueue(0);
        while (queue.Count() > 0)
        {
            var now = queue.Dequeue();
            foreach (var next in dict[now])
            {
                if (from[next] != -1) continue;
                from[next] = now;
                queue.Enqueue(next);
            }
        }

        if (from.Count(e => e == -1) > 1)
        {
            Output("NO");
            return;
        }
        Output("YES");
        for (int i = 1; i < N; i++)
        {
            Console.WriteLine((i + 1) + " " + (from[i] + 1));
        }

    }
}


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;

public static class Ex
{
    public static bool IsNullOrEmpty(this string s) { return string.IsNullOrEmpty(s); }
    public static void yesno(this bool b) => Console.WriteLine(b ? "yes" : "no");
    public static void YesNo(this bool b) => Console.WriteLine(b ? "Yes" : "No");
    public static void YESNO(this bool b) => Console.WriteLine(b ? "YES" : "NO");
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    //public static bool Chmax<T>(ref this T a, T b) where T : struct, IComparable<T>
    //{
    //    if (b.CompareTo(a) > 0) { a = b; return true; }
    //    else return false;
    //}
    //[MethodImpl(MethodImplOptions.AggressiveInlining)]
    //public static bool Chmin<T>(ref this T a, T b) where T : struct, IComparable<T>
    //{
    //    if (b.CompareTo(a) < 0) { a = b; return true; }
    //    else return false;
    //}

    public static List<string> FastSort(this List<string> s) { s.Sort(StringComparer.OrdinalIgnoreCase); return s.ToList(); }

    public static int PopCount(this uint bits)
    {
        bits = (bits & 0x55555555) + (bits >> 1 & 0x55555555);
        bits = (bits & 0x33333333) + (bits >> 2 & 0x33333333);
        bits = (bits & 0x0f0f0f0f) + (bits >> 4 & 0x0f0f0f0f);
        bits = (bits & 0x00ff00ff) + (bits >> 8 & 0x00ff00ff);
        return (int)((bits & 0x0000ffff) + (bits >> 16 & 0x0000ffff));
    }
}

partial class Program
{
    string GetStr() { return Console.ReadLine().Trim(); }
    char GetChar() { return Console.ReadLine().Trim()[0]; }
    int GetInt() { return int.Parse(Console.ReadLine().Trim()); }
    long GetLong() { return long.Parse(Console.ReadLine().Trim()); }
    double GetDouble() { return double.Parse(Console.ReadLine().Trim()); }
    string[] GetStrArray() { return Console.ReadLine().Trim().Split(' '); }
    string[][] GetStrArray(int N)
    {
        var res = new string[N][];
        for (int i = 0; i < N; i++) res[i] = Console.ReadLine().Trim().Split(' ');
        return res;
    }
    int[] GetIntArray() { return Console.ReadLine().Trim().Split(' ').Select(int.Parse).ToArray(); }
    int[][] GetIntArray(int N)
    {
        var res = new int[N][];
        for (int i = 0; i < N; i++) res[i] = Console.ReadLine().Trim().Split(' ').Select(int.Parse).ToArray();
        return res;
    }
    public long[] GetLongArray() { return Console.ReadLine().Trim().Split(' ').Select(long.Parse).ToArray(); }
    long[][] GetLongArray(int N)
    {
        var res = new long[N][];
        for (int i = 0; i < N; i++) res[i] = Console.ReadLine().Trim().Split(' ').Select(long.Parse).ToArray();
        return res;
    }
    char[] GetCharArray() { return Console.ReadLine().Trim().Split(' ').Select(char.Parse).ToArray(); }
    double[] GetDoubleArray() { return Console.ReadLine().Trim().Split(' ').Select(double.Parse).ToArray(); }
    double[][] GetDoubleArray(int N)
    {
        var res = new double[N][];
        for (int i = 0; i < N; i++) res[i] = Console.ReadLine().Trim().Split(' ').Select(double.Parse).ToArray();
        return res;
    }
    char[][] GetGrid(int H)
    {
        var res = new char[H][];
        for (int i = 0; i < H; i++) res[i] = Console.ReadLine().Trim().ToCharArray();
        return res;
    }
    T[] CreateArray<T>(int N, T value)
    {
        var res = new T[N];
        for (int i = 0; i < N; i++) res[i] = value;
        return res;
    }
    T[][] CreateArray<T>(int H, int W, T value)
    {
        var res = new T[H][];
        for (int i = 0; i < H; i++)
        {
            res[i] = new T[W];
            for (int j = 0; j < W; j++) res[i][j] = value;
        }
        return res;
    }
    T[][][] CreateArray<T>(int H, int W, int R, T value)
    {
        var res = new T[H][][];
        for (int i = 0; i < H; i++)
        {
            res[i] = new T[W][];
            for (int j = 0; j < W; j++)
            {
                res[i][j] = new T[R];
                for (int k = 0; k < R; k++) res[i][j][k] = value;
            }
        }
        return res;
    }

    Dictionary<int, List<int>> GetUnweightedAdjacencyList(int N, int M, bool isDirected, bool isNode_0indexed)
    {
        var dic = new Dictionary<int, List<int>>();
        foreach (var e in Enumerable.Range(0, N)) { dic.Add(e, new List<int>()); }
        for (int i = 0; i < M; i++)
        {
            var input = GetIntArray();
            var a = isNode_0indexed ? input[0] : input[0] - 1;
            var b = isNode_0indexed ? input[1] : input[1] - 1;
            dic[a].Add(b);
            if (isDirected == false) dic[b].Add(a);
        }
        return dic;
    }
    //Dictionary<int, List<(int node, long cost)>> GetWeightedAdjacencyList(int N, int M, bool isDirected, bool isNode_0indexed)
    //{
    //    var dic = new Dictionary<int, List<(int, long)>>();
    //    foreach (var e in Enumerable.Range(0, N)) { dic.Add(e, new List<(int, long)>()); }
    //    for (int i = 0; i < M; i++)
    //    {
    //        var input = GetIntArray();
    //        var a = isNode_0indexed ? input[0] : input[0] - 1;
    //        var b = isNode_0indexed ? input[1] : input[1] - 1;
    //        var c = input[2];
    //        dic[a].Add((b, c));
    //        if (isDirected == false) dic[b].Add((a, c));
    //    }
    //    return dic;
    //}

    bool eq<T, U>() => typeof(T).Equals(typeof(U));
    T ct<T, U>(U a) => (T)Convert.ChangeType(a, typeof(T));
    T cv<T>(string s) => eq<T, int>() ? ct<T, int>(int.Parse(s))
                       : eq<T, long>() ? ct<T, long>(long.Parse(s))
                       : eq<T, double>() ? ct<T, double>(double.Parse(s))
                       : eq<T, char>() ? ct<T, char>(s[0])
                                         : ct<T, string>(s);
    void Multi<T>(out T a) => a = cv<T>(GetStr());
    void Multi<T, U>(out T a, out U b)
    {
        var ar = GetStrArray(); a = cv<T>(ar[0]); b = cv<U>(ar[1]);
    }
    void Multi<T, U, V>(out T a, out U b, out V c)
    {
        var ar = GetStrArray(); a = cv<T>(ar[0]); b = cv<U>(ar[1]); c = cv<V>(ar[2]);
    }
    void Multi<T, U, V, W>(out T a, out U b, out V c, out W d)
    {
        var ar = GetStrArray(); a = cv<T>(ar[0]); b = cv<U>(ar[1]); c = cv<V>(ar[2]); d = cv<W>(ar[3]);
    }
    void Multi<T, U, V, W, X>(out T a, out U b, out V c, out W d, out X e)
    {
        var ar = GetStrArray(); a = cv<T>(ar[0]); b = cv<U>(ar[1]); c = cv<V>(ar[2]); d = cv<W>(ar[3]); e = cv<X>(ar[4]);
    }
    void Multi<T, U, V, W, X, Y>(out T a, out U b, out V c, out W d, out X e, out Y f)
    {
        var ar = GetStrArray(); a = cv<T>(ar[0]); b = cv<U>(ar[1]); c = cv<V>(ar[2]); d = cv<W>(ar[3]); e = cv<X>(ar[4]); f = cv<Y>(ar[5]);
    }

    void Output<T>(T t) => Console.WriteLine(t);
    void Output<T>(IList<T> ls) => Console.WriteLine(string.Join(" ", ls));
    void Debug<T>(IList<IList<T>> ls)
    {
        foreach (var l in ls)
            foreach (var s in l)
                Console.WriteLine(s);
    }

    void Swap<T>(ref T a, ref T b) { T temp = a; a = b; b = temp; }

    int[] dx = new int[] { 1, 0, -1, 0, 1, -1, -1, 1 };
    int[] dy = new int[] { 0, 1, 0, -1, 1, 1, -1, -1 };
    long mod = 1000000007;
}

partial class Program
{
    static void Main()
    {
        Console.SetIn(new StreamReader(Console.OpenStandardInput(8192)));
        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
        new Program().Solve();
        Console.Out.Flush();
        Console.Read();
    }

    public void Solve()
    {
        int T = GetInt();
        for(int i = 0; i < T; i++)
        {
            SolveSolve();
        }
    }

    void SolveSolve()
    {
        int N = GetInt();
        var A = GetIntArray();
        var dict = new Dictionary<int, HashSet<int>>();
        for (int i = 0; i < N; i++) dict.Add(i, new HashSet<int>());
        for (int i = 0; i < N; i++)
        {
            for (int j = i + 1; j < N; j++)
            {
                if (A[i] != A[j])
                {
                    dict[i].Add(j);
                    dict[j].Add(i);
                }
            }
        }

        var from = new int[N].Select(e => -1).ToArray();
        var queue = new Queue<int>();
        queue.Enqueue(0);
        while (queue.Count() > 0)
        {
            var now = queue.Dequeue();
            foreach (var next in dict[now])
            {
                if (from[next] != -1) continue;
                from[next] = now;
                queue.Enqueue(next);
            }
        }

        if (from.Count(e => e == -1) > 1)
        {
            Output("NO");
            return;
        }
        Output("YES");
        for (int i = 1; i < N; i++)
        {
            Console.WriteLine((i + 1) + " " + (from[i] + 1));
        }
    }
}