#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cctype>
#include <cstdio>
#include <iomanip>
#include <sstream>
#include <cstdlib>
#include <cassert>
#include <climits>
#include <complex>
#include <numeric>
#include <valarray>
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;

#define inf 1061109567
#define pb push_back
#define mp make_pair
#define all(a) a.begin(),a.end()
#define mem(x,a) memset(x,a,sizeof(x))
#define rep(i,n) for(int i(0),_n(n);i<_n;++i)
#define repi(i,a,b) for(int i(a),_b(b);i<_b;++i)
#define repe(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();++it)
#define len(x) ((int)(x.size()))

#define DEBUG 1
#if DEBUG && !ONLINE_JUDGE
	#define debug(args...) (Debugger()) , args
	class Debugger { public: Debugger(const std::string& _separator = ", ") : first(true), separator(_separator){} template<typename ObjectType> Debugger& operator , (const ObjectType& v) { if(!first) std::cerr << separator; std::cerr << v; first = false; return *this; } ~Debugger() { std::cerr << endl;} private: bool first; std::string separator; }; template <typename T1, typename T2> inline std::ostream& operator << (std::ostream& os, const std::pair<T1, T2>& p) { return os << "(" << p.first << ", " << p.second << ")"; } template<typename T> inline std::ostream &operator << (std::ostream & os,const std::vector<T>& v) { bool first = true; os << "["; for(unsigned int i = 0; i < v.size(); i++) { if(!first) os << ", "; os << v[i]; first = false; } return os << "]"; } template<typename T> inline std::ostream &operator << (std::ostream & os,const std::set<T>& v) { bool first = true; os << "["; for (typename std::set<T>::const_iterator ii = v.begin(); ii != v.end(); ++ii) { if(!first) os << ", "; os << *ii; first = false; } return os << "]"; } template<typename T1, typename T2> inline std::ostream &operator << (std::ostream & os,const std::map<T1, T2>& v) { bool first = true; os << "["; for (typename std::map<T1, T2>::const_iterator ii = v.begin(); ii != v.end(); ++ii) { if(!first) os << ", "; os << *ii ; first = false; } return os << "]"; }
#else
		#define debug(args...)
#endif

int n,t1,t2;
vector<pair<int,int> > vp;
vector<pair<int,int> > v;

int main(){
	ios_base::sync_with_stdio(0);

	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);

	cin>>n;
	rep(i,n*2){
		cin>>t1;
		v.pb(mp(t1,i+1));
	}

	sort(all(v));

	//debug(v);

	rep(i,n*2){

		if(v[i].first==v[i+1].first){
			vp.pb(mp(v[i].second,v[i+1].second));
			i++;
		}
		else {
			cout<<-1;
			return 0;
		}

	}

	rep(i,n){
		cout<<vp[i].first<<" "<<vp[i].second<<endl;
	}

}


#include<vector>
#include<iostream>
#include<fstream>
#include<sstream>
#include<algorithm>

using namespace std;

class Task {
    string answer = "";
    vector<pair<int, int> > a;

public:
    void getData() {
        ifstream fin("input.txt");

        int numberOfPairs;
        fin >> numberOfPairs;
        //cin >> numberOfPairs;
        a.resize(numberOfPairs * 2);

        for (size_t i = 0; i < a.size(); ++i) {
            fin >> a[i].first;
            a[i].second = i + 1;
        }

    }

    void solve() {
        sort(a.begin(), a.end());
        for (size_t i = 1; i < a.size(); i += 2) {
            if (a[i - 1].first < a[i].first) {
                answer = "-1";
                return;
            }
            ostringstream converter;
            converter << a[i - 1].second << " " << a[i].second << endl;
            answer += converter.str();
        }
    }

    void printAnswer() {
        ofstream fout("output.txt");
        fout << answer;
        //cout << answer;
    }
};

int main() {
    Task task = Task();
    task.getData();
    task.solve();
    task.printAnswer();

    return 0;
}


#include<vector>
#include<iostream>
#include<fstream>
#include<sstream>
#include<algorithm>

using namespace std;

class Task {
    string answer = "";
    vector<pair<int, int> > a;

public:
    void getData() {
        ifstream fin("input.txt");

        int numberOfPairs;
        fin >> numberOfPairs;
        //cin >> numberOfPairs;
        a.resize(numberOfPairs * 2);

        for (size_t i = 0; i < a.size(); ++i) {
            fin >> a[i].first);
            a[i].second = i + 1;
        }

    }

    void solve() {
        sort(a.begin(), a.end());
        for (size_t i = 1; i < a.size(); i += 2) {
            if (a[i - 1].first < a[i].first) {
                answer = "-1";
                return;
            }
            ostringstream converter;
            converter << a[i - 1].second << " " << a[i].second << endl;
            answer += converter.str();
        }
    }

    void printAnswer() {
        ofstream fout("output.txt");
        fout << answer;
        //cout << answer;
    }
};

int main() {
    Task task = Task();
    task.getData();
    task.solve();
    task.printAnswer();

    return 0;
}


#include<vector>
#include<iostream>
#include<fstream>
#include<sstream>
#include<algorithm>

using namespace std;

class Task {
    string answer = "";
    vector<pair<int, int> > a;

public:
    void getData() {
        ifstream fin("input.txt");

        int numberOfPairs;
        fin >> numberOfPairs;
        //cin >> numberOfPairs;
        a.resize(numberOfPairs * 2);

        for (size_t i = 0; i < a.size(); ++i) {
            scanf("%d", &a[i].first);
            a[i].second = i + 1;
        }

    }

    void solve() {
        sort(a.begin(), a.end());
        for (size_t i = 1; i < a.size(); i += 2) {
            if (a[i - 1].first < a[i].first) {
                answer = "-1";
                return;
            }
            ostringstream converter;
            converter << a[i - 1].second << " " << a[i].second << endl;
            answer += converter.str();
        }
    }

    void printAnswer() {
        ofstream fout("output.txt");
        fout << answer;
        //cout << answer;
    }
};

int main() {
    Task task = Task();
    task.getData();
    task.solve();
    task.printAnswer();

    return 0;
}


#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<vector>
using namespace std;
#define fr(i,n) for(int i=0;i<n;i++)
#define fo(i,n) for(int i=1;i<=n;i++)
#define fe(i,n) for(__typeof(n.begin()) i=n.begin();i!=n.end();i++)
#define X first
#define Y second
typedef pair<int,int>ii;
ii a[600020];
int n;
int main()
{
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
	scanf("%d",&n);
	fr(i,n*2)
		scanf("%d",&a[i].X),a[i].Y=i;
	sort(a,a+2*n);
	for(int i=0;i<n*2;i+=2)
		if(a[i].X!=a[i+1].X)
			return puts("-1"),0;
	for(int i=0;i<n*2;i+=2)
		printf("%d %d\n",a[i].Y+1,a[i+1].Y+1);
}


#include <iostream>
#include <cstdio>
#include <map>
#include <algorithm>

using namespace std;

const int MAXN = 1000005;
pair<int, int> a[MAXN];
map<int, int> mp;

int main() {
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    int n;

    cin >> n;
    for (int i = 0; i < 2 * n; ++i) {
        cin >> a[i].first;
        a[i].second = i + 1;
        ++mp[a[i].first];
    }
    for (map<int, int>::iterator i = mp.begin(); i != mp.end(); ++i) {
        if (i->second & 1) {
            puts("-1");
            return 0;
        }
    }
    sort(a, a + 2 * n);
    for (int i = 0; i < 2 * n; i += 2) {
        printf("%d %d\n", a[i].second, a[i + 1].second);
    }

    return 0;
}


#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
#include <vector>

using namespace std;

typedef long long ll;

const ll INF = 1e9;
const double EPS = 1e-9;

int n;

int main() {
    cin >> n;
    vector <pair<int, int> > ans;
    vector< pair<int, int> >v(n*2);
    for (int i = 0; i < n*2; i++) {
        cin >> v[i].first;
        v[i].second = i+1;
    }
    sort(v.begin(), v.end());
    for (int i = 0; i < n*2; i+=2) {
        if (v[i].first == v[i+1].first) {
            ans.push_back(make_pair(v[i].second, v[i+1].second));
        } else {
            cout << -1;
            return 0;
        }
    }
    for (int i = 0; i < n; i++) {
        cout << ans[i].first << " " << ans[i].second << endl;
    }

}


#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
#include <vector>

using namespace std;

typedef long long ll;

const ll INF = 1e9;
const double EPS = 1e-9;

int n;

int main() {
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    ios_base::sync_with_stdio(false);
    cin >> n;
    vector <pair<int, int> > ans(n);
    vector< pair<int, int> >v(n*2);
    for (int i = 0; i < n*2; i++) {
        cin >> v[i].first;
        v[i].second = i+1;
    }
    sort(v.begin(), v.end());
    for (int i = 0; i < n*2; i+=2) {
        if (v[i].first == v[i+1].first) {
            ans[i/2] = make_pair(v[i].second, v[i+1].second);
        } else {
            cout << -1;
            return 0;
        }
    }
    for (int i = 0; i < n; i++) {
        cout << ans[i].first << " " << ans[i].second << endl;
    }

}


#include <algorithm>
#include <cstdio>
#include <vector>

using namespace std;

typedef pair<int, int> ii;

int main() {
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);

    vector<ii> v, ans;
    int n, a;
    scanf("%d\n", &n);

    for (int i=1 ; i<=2*n ; i++) {
        scanf("%d", &a);
        v.push_back(ii(a, i));
    }

    sort(v.begin(), v.end());

    for (int i=1 ; i<v.size() ; i+=2) {
        if (v[i].first == v[i-1].first) {
            ans.push_back(ii(v[i].second, v[i-1].second));
        }
        else {
            printf("-1\n");
            return 0;
        }
    }

    for (int i=0 ; i<ans.size() ; i++) {
        printf("%d %d\n", ans[i].first, ans[i].second);
    }
}


#include <algorithm>
#include <cstdio>
#include <vector>

using namespace std;

typedef pair<int, int> ii;

int main() {
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);

    vector<ii> v;
    int n, a;
    scanf("%d\n", &n);

    for (int i=1 ; i<=2*n ; i++) {
        scanf("%d", &a);
        v.push_back(ii(a, i));
    }

    sort(v.begin(), v.end());

    for (int i=1 ; i<v.size() ; i+=2) {
        if (v[i].first == v[i-1].first) {
            printf("%d %d\n", v[i].second, v[i-1].second);
        }
        else {
            printf("-1\n");
            return 0;
        }
    }
}


#include<stdio.h>
#include<string.h>

int main(){
	int num[5005];
	memset(num,-1,5005*sizeof(int));
	int n,x;
	scanf("%d",&n);
	for(int i=0;i<2*n;i++){
		scanf("%d",&x);
		if(num[x]==-1){
			num[x]=i+1;
		}
		else
		{
			printf("%d %d\n",num[x],i+1);

			num[x]=-1;
		}
	}

	return 0;
}


#include<stdio.h>
#include<string.h>

int main(){
	int num[5005];
	int ans[600005];
	int count=0;
	int n,x;
	    freopen("input.txt", "r", stdin);
	        freopen("output.txt", "w", stdout);
	scanf("%d",&n);
	for(int i=0;i<5005;i++)
		num[i]=-1;
	for(int i=0;i<2*n;i++){
		scanf("%d",&x);
		if(num[x]==-1){
			num[x]=i+1;
		}
		else
		{
			ans[count++]=num[x];
			ans[count++]=i+1;
			num[x]=-1;
		}
	}
	if(count==2*n)
	{
		for(int i=0;i<count;i=i+2){
			printf("%d %d\n",ans[i],ans[i+1]);
		}
	}
	else
		printf("-1\n");

	return 0;
}


#include<stdio.h>
#include<string.h>

int main(){
	int num[5005];
	memset(num,-1,5005*sizeof(int));
	int ans[600005];
	int count=0;
	int n,x;
	scanf("%d",&n);
	for(int i=0;i<2*n;i++){
		scanf("%d",&x);
		if(num[x]==-1){
			num[x]=i+1;
		}
		else
		{
			ans[count++]=num[x];
			ans[count++]=i+1;
			num[x]=-1;
		}
	}
	if(count==2*n)
	{
		for(int i=0;i<count;i=i+2){
			printf("%d %d\n",ans[i],ans[i+1]);
		}
	}
	else
		printf("-1\n");

	return 0;
}


#include<stdio.h>
#include<string.h>

int main(){
	int num[5005];
	int ans[600005];
	int count=0;
	int n,x;
	scanf("%d",&n);
	for(int i=0;i<5005;i++)
		num[i]=-1;
	for(int i=0;i<2*n;i++){
		scanf("%d",&x);
		if(num[x]==-1){
			num[x]=i+1;
		}
		else
		{
			ans[count++]=num[x];
			ans[count++]=i+1;
			num[x]=-1;
		}
	}
	if(count==2*n)
	{
		for(int i=0;i<count;i=i+2){
			printf("%d %d\n",ans[i],ans[i+1]);
		}
	}
	else
		printf("-1\n");

	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include <numeric>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <fstream>

#define REP(I, N) for (int I = 0; I < (N); ++I)
#define PER(I, N) for (int I = (N); I >= 0; --I)
#define PERR(I, A, B) for (int I = (A); I >= (B); --I)
#define REPP(I, A, B) for (int I = (A); I <  (B); ++I)
#define REPN(I, A, B) for (int I = (A); I <= (B); ++I)
#define REPC(I, A, C) for (int I = (A); (C); ++I)
#define REPPP(I, A, B, C) for (int I = (A); I <  (B); I += C)
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define RIIII(X, Y, Z, W) scanf("%d%d%d%d", &(X), &(Y), &(Z), &(W))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define DRIIII(X, Y, Z, W) int X, Y, Z, W; scanf("%d%d%d%d", &X, &Y, &Z, &W)
#define RS(X) scanf("%s", (X))
#define LEN(X) (int(strlen(X)))
#define SZ(X) (int((X).size()))
#define SUM(X, N) accumulate(X, X + (N), 0)
#define MS0(X) memset((X), 0, sizeof(X))
#define MSI(X) memset((X), 0xFF, sizeof(X))
#define BITS(X) ((int)__builtin_popcount(X))
#define F first
#define S second
#define MP make_pair
#define PB push_back

#ifdef DK
const int MAX = 100 + 11;
#else
const int MAX = 1e5 + 11;
#endif

using namespace std;

int C[5555];

int main() {
#ifdef DK
  freopen("in.txt", "r", stdin);
#else
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  vector<pair<int, int>> A;
  DRI(N);
  REP(i, 2 * N) {
    DRI(x);
    C[x]++;
    A.PB(MP(x, i));
  }
  REP(i, 5001) {
    if (C[i] % 2 == 1) {
      printf("-1");
      return 0;
    }
  }
  sort(A.begin(), A.end());
  for (int i = 0; i < 2 * N; i += 2) {
    printf("%d %d\n", A[i].S + 1, A[i + 1].S + 1);
  }
  return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include <numeric>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <fstream>

#define REP(I, N) for (int I = 0; I < (N); ++I)
#define PER(I, N) for (int I = (N); I >= 0; --I)
#define PERR(I, A, B) for (int I = (A); I >= (B); --I)
#define REPP(I, A, B) for (int I = (A); I <  (B); ++I)
#define REPN(I, A, B) for (int I = (A); I <= (B); ++I)
#define REPC(I, A, C) for (int I = (A); (C); ++I)
#define REPPP(I, A, B, C) for (int I = (A); I <  (B); I += C)
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define RIIII(X, Y, Z, W) scanf("%d%d%d%d", &(X), &(Y), &(Z), &(W))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define DRIIII(X, Y, Z, W) int X, Y, Z, W; scanf("%d%d%d%d", &X, &Y, &Z, &W)
#define RS(X) scanf("%s", (X))
#define LEN(X) (int(strlen(X)))
#define SZ(X) (int((X).size()))
#define SUM(X, N) accumulate(X, X + (N), 0)
#define MS0(X) memset((X), 0, sizeof(X))
#define MSI(X) memset((X), 0xFF, sizeof(X))
#define BITS(X) ((int)__builtin_popcount(X))
#define F first
#define S second
#define MP make_pair
#define PB push_back

#ifdef DK
const int MAX = 100 + 11;
#else
const int MAX = 1e5 + 11;
#endif

using namespace std;

int C[5555];

int main() {
#ifdef DK
  freopen("in.txt", "r", stdin);
#endif
  vector<pair<int, int>> A;
  DRI(N);
  REP(i, 2 * N) {
    DRI(x);
    C[x]++;
    A.PB(MP(x, i));
  }
  REP(i, 5001) {
    if (C[i] % 2 == 1) {
      printf("-1");
      return 0;
    }
  }
  sort(A.begin(), A.end());
  for (int i = 0; i < 2 * N; i += 2) {
    printf("%d %d\n", A[i].S + 1, A[i + 1].S + 1);
  }
  return 0;
}


#include <iostream>
#include <vector>
#include <cstdio>
#include <stdio.h>
using namespace std;
int main() {
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    int n;
    cin >> n;
        int temp;
    vector<vector<int> > ns(5001);
    for (int i = 0; i < 2 * n; i++) {
        cin >> temp;
        ns[temp].push_back(i+1);
        }
    vector<int> out;
    for (int i = 0; i <= 5000; i++) {
        if (ns[i].size() % 2) {
            cout << -1 << endl;
            return 0;
        }
        for (int j = 0; j < ns[i].size(); j++) {
            out.push_back(ns[i][j]);
        }
    }
    if (out.size() != 2*n) {
        cout << -1 << endl;
    }
    else {
        for (int i = 0; i < out.size(); i++) {
            cout << out[i] << " ";
            if (i % 2) cout << endl;
        }
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <cstdio>
#include <map>
#include <stdio.h>
using namespace std;
int main() {
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    int n;
    cin >> n;
    int temp;
    map<int, vector<int> > ns;
    for (int i = 0; i < 2 * n; i++) {
        cin >> temp;
        ns[temp].push_back(i + 1);
    }
    vector<int> out;
    map<int, vector<int> > ::iterator it;
    for (it = ns.begin(); it != ns.end(); it++) {
        if (it->second.size() % 2) {
            cout << -1 << endl;
            return 0;
        }
        for (int j = 0; j < it->second.size(); j++) {
            out.push_back(it->second[j]);
        }
    }
        for (int i = 0; i < out.size(); i++) {
            cout << out[i] << " ";
            if (i % 2) cout << endl;
        }
    return 0;
}


#include <iostream>
#include <vector>
using namespace std;
int main() {
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
    int n;
    cin >> n;
        int temp;
    vector<vector<int> > ns(5001);
    for (int i = 0; i < 2 * n; i++) {
        cin >> temp;
        ns[temp].push_back(i+1);
        }
    vector<int> out;
    for (int i = 0; i <= 5000; i++) {
        if (ns[i].size() % 2) {
            cout << -1 << endl;
            return 0;
        }
        for (int j = 0; j < ns[i].size(); j++) {
            out.push_back(ns[i][j]);
        }
    }
    if (out.size() != 2*n) {
        cout << -1 << endl;
    }
    else {
        for (int i = 0; i < out.size(); i++) {
            cout << out[i] << " ";
            if (i % 2) cout << endl;
        }
    }
    return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <fstream>
using namespace std;
int main()
{
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    int n, f[5001], p[300000], q[300000], m = 0;
    cin >> n;
    memset(f, 0, sizeof(f));
    for(int i = 1, j; i <= (n << 1); i++)
    {
        cin >> j;
        if(f[j])
        {
            p[m] = i;
            q[m++] = f[j];
            f[j] = 0;
        }
        else
            f[j] = i;
    }
    for(int i = 1; i <= 5000; i++)
        if(f[i])
        {
            cout << -1 << endl;
            return 0;
        }
    for(int i = 0; i < m; i++)
        cout << p[i] << ' ' << q[i] << endl;
    return 0;
}


#pragma comment(linker, "/STACK:16777216")
#include <iostream>
#include <set>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <math.h>
#include <string>
#include <map>
#include <stdlib.h>
#include <sstream>
#include <memory.h>
//#include <ctime>
//#include <fstream>
using namespace std;

using namespace std;

#define FOR(i, a, b) for(int i = (a); i < (b); ++i)
#define RFOR(i, b, a) for(int i = (b) - 1; i >= (a); --i)
#define REP(i, N) FOR(i, 0, N)
#define ALL(V) V.begin(),V.end()
#define SZ(V) (int)V.size()

double const PI = acos(-1.0);
double const EPS=1e-8;

#define INF 1000000000
#define MP make_pair
#define FILL(A,value) memset(A,value,sizeof(A))
#define MOD 1000000009

pair<int,int> a[700000];

vector<pair<int,int> >res;

int main(){

	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);

	int n;
	scanf("%d",&n);

	n*=2;

	REP(i,n){
		scanf("%d",&a[i].first);
		a[i].second=i+1;
	}

	sort(a,a+n);

	for (int i=0; i<n; i+=2){
		if (a[i].first!=a[i+1].first){
			cout<<-1<<endl;
			return 0;
		}
		res.push_back(MP(a[i].second,a[i+1].second));
	}

	REP(i,SZ(res)){
		printf("%d %d\n",res[i].first,res[i].second);
	}

}


#pragma comment(linker, "/STACK:16777216")
#include <iostream>
#include <set>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <math.h>
#include <string>
#include <map>
#include <stdlib.h>
#include <sstream>
#include <memory.h>
//#include <ctime>
//#include <fstream>
using namespace std;

using namespace std;

#define FOR(i, a, b) for(int i = (a); i < (b); ++i)
#define RFOR(i, b, a) for(int i = (b) - 1; i >= (a); --i)
#define REP(i, N) FOR(i, 0, N)
#define ALL(V) V.begin(),V.end()
#define SZ(V) (int)V.size()

double const PI = acos(-1.0);
double const EPS=1e-8;

#define INF 1000000000
#define MP make_pair
#define FILL(A,value) memset(A,value,sizeof(A))
#define MOD 1000000009

pair<int,int> a[700000];

vector<pair<int,int> >res;

int main(){

	int n;
	scanf("%d",&n);

	n*=2;

	REP(i,n){
		scanf("%d",&a[i].first);
		a[i].second=i+1;
	}

	sort(a,a+n);

	for (int i=0; i<n; i+=2){
		if (a[i].first!=a[i+1].first){
			cout<<-1<<endl;
			return 0;
		}
		res.push_back(MP(a[i].second,a[i+1].second));
	}

	REP(i,SZ(res)){
		printf("%d %d\n",res[i].first,res[i].second);
	}

}


#pragma comment(linker, "/STACK:16777216")
#include <iostream>
#include <set>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <math.h>
#include <string>
#include <map>
#include <stdlib.h>
#include <sstream>
#include <memory.h>
//#include <ctime>
//#include <fstream>
using namespace std;

using namespace std;

#define FOR(i, a, b) for(int i = (a); i < (b); ++i)
#define RFOR(i, b, a) for(int i = (b) - 1; i >= (a); --i)
#define REP(i, N) FOR(i, 0, N)
#define ALL(V) V.begin(),V.end()
#define SZ(V) (int)V.size()

double const PI = acos(-1.0);
double const EPS=1e-8;

#define INF 1000000000
#define MP make_pair
#define FILL(A,value) memset(A,value,sizeof(A))
#define MOD 1000000009

pair<int,int> a[700000];

vector<pair<int,int> >res;

int main(){

	freopen("inupt.txt","r",stdin);
	freopen("output.txt","w",stdout);

	int n;
	scanf("%d",&n);

	n*=2;

	REP(i,n){
		scanf("%d",&a[i].first);
		a[i].second=i+1;
	}

	sort(a,a+n);

	for (int i=0; i<n; i+=2){
		if (a[i].first!=a[i+1].first){
			cout<<-1<<endl;
			return 0;
		}
		res.push_back(MP(a[i].second,a[i+1].second));
	}

	REP(i,SZ(res)){
		printf("%d %d\n",res[i].first,res[i].second);
	}

}


#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

int main() {
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    int n;
    fin>>n;
    vector< vector<int> > v(5001);
    for(int i=0; i<n*2; ++i) {
        int a;
        fin>>a;
        v[a].push_back(i+1);
    }

    for(int i=0; i<v.size(); ++i) {

        if(v[i].size()%2==1) {
            fout<<-1<<'\n';
            return 0;
        }
    }
    for(int i=0; i<v.size(); ++i) {
        for(int j=0; j<v[i].size(); j+=2) {
            fout<<v[i][j]<<' '<<v[i][j+1]<<'\n';
        }
    }

}


#include<iostream>
#include<cstdlib>
#include<complex>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 3*100000 + 100
struct Dot
{
    int number;
    int x;
};
struct Dot a[MAXN];
int b[5000+50];
bool comp(const Dot &a,const Dot &b);
bool pairs();
int main()
{
//    freopen("data.txt","r",stdin);
    memset(b,0,sizeof(b));
    int n;
    cin>>n;
    int i;
    for(i=0;i<2*n;i++)
    {
        scanf("%d",&a[i].number);
        a[i].x=i+1;
        b[a[i].number]+=1;
    }
    if(!pairs()) printf("-1\n");
    else
    {
        sort(a,a+2*n,comp);
        for(i=0;i<n;i++)
        {
            printf("%d %d\n",a[2*i].x,a[2*i+1].x);
        }
    }
    return 0;
}

bool comp(const Dot &a,const Dot &b)
{
    return a.number<b.number;
}

bool pairs()
{
    int i,ok=1;
    for(i=1;i<=5000;i++)
    {
        if(b[i]%2)
        {
            ok=0;
            break;
        }
    }
    if(ok) return true;
    else return false;
}


#include<iostream>
#include<cstdlib>
#include<complex>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 3*100000 + 100
struct Dot
{
    int number;
    int x;
};
struct Dot a[MAXN];
int b[5000+50];
bool comp(const Dot &a,const Dot &b);
bool pairs();
int compare(const void *a,const void *b);
int main()
{
//    freopen("data.txt","r",stdin);
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    memset(b,0,sizeof(b));
    int n;
    cin>>n;
    int i;
    for(i=0;i<2*n;i++)
    {
        scanf("%d",&a[i].number);
        a[i].x=i+1;
        b[a[i].number]+=1;
    }
    if(!pairs()) printf("-1\n");
    else
    {
//        sort(a,a+2*n,comp);
        qsort(a,2*n,sizeof(Dot),compare);
        for(i=0;i<n;i++)
        {
            printf("%d %d\n",a[2*i].x,a[2*i+1].x);
        }
    }
    return 0;
}

int compare(const void *a,const void *b)
{
    Dot *c=(Dot*)a, *d=(Dot*)b;
    if((c->number)-(d->number)>0) return 1;
    else if((c->number)-(d->number)==0) return 0;
    else return -1;
}

bool comp(const Dot &a,const Dot &b)
{
    return a.number<b.number;
}

bool pairs()
{
    int i,ok=1;
    for(i=1;i<=5000;i++)
    {
        if(b[i]%2)
        {
            ok=0;
            break;
        }
    }
    if(ok) return true;
    else return false;
}


#include<iostream>
#include<cstdlib>
#include<complex>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 6*100000 + 100
struct Dot
{
    int number;
    int x;
};
struct Dot a[MAXN];
int b[5000+50];
bool comp(const Dot &a,const Dot &b);
bool pairs();
int compare(const void *a,const void *b);
int main()
{
//    freopen("data.txt","r",stdin);
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    memset(b,0,sizeof(b));
    int n;
    cin>>n;
    int i;
    for(i=0;i<2*n;i++)
    {
        scanf("%d",&a[i].number);
        a[i].x=i+1;
        b[a[i].number]+=1;
    }
    if(!pairs()) printf("-1\n");
    else
    {
        //    qsort(a,2*n,sizeof(Dot),compare);
        sort(a,a+2*n,comp);
        for(i=0;i<n;i++)
        {
            printf("%d %d\n",a[2*i].x,a[2*i+1].x);
        }
    }
    return 0;
}

int compare(const void *a,const void *b)
{
    Dot *c=(Dot*)a, *d=(Dot*)b;
    if((c->number)-(d->number)>0) return 1;
    else if((c->number)-(d->number)==0) return 0;
    else return -1;
}

bool comp(const Dot &a,const Dot &b)
{
    return a.number<b.number;
}

bool pairs()
{
    int i,ok=1;
    for(i=1;i<=5000;i++)
    {
        if(b[i]%2)
        {
            ok=0;
            break;
        }
    }
    if(ok) return true;
    else return false;
}


#include<iostream>
#include<cstdlib>
#include<complex>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 3*100000 + 100
struct Dot
{
    int number;
    int x;
};
struct Dot a[MAXN];
int b[5000+50];
bool comp(const Dot &a,const Dot &b);
bool pairs();
int main()
{
//    freopen("data.txt","r",stdin);
    memset(b,0,sizeof(b));
    int n;
    cin>>n;
    int i;
    for(i=0;i<2*n;i++)
    {
        scanf("%d",&a[i].number);
        a[i].x=i+1;
        b[a[i].number]+=1;
    }
    if(!pairs()) printf("-1\n");
    else
    {
        sort(a,a+2*n,comp);
        for(i=0;i<n;i++)
        {
            printf("%d %d\n",a[2*i].x,a[2*i+1].x);
        }
    }
    return 0;
}

bool comp(const Dot &a,const Dot &b)
{
    return a.number<b.number;
}

bool pairs()
{
    int i,ok=1;
    for(i=1;i<=5000;i++)
    {
        if(b[i]%2)
        {
            ok=0;
            break;
        }
    }
    if(ok) return true;
    else return false;
}


#include<iostream>
#include<cstdlib>
#include<complex>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 3*100000 + 100
struct Dot
{
    int number;
    int x;
};
struct Dot a[MAXN];
int b[5000+50];
bool comp(const Dot &a,const Dot &b);
bool pairs();
int compare(const void *a,const void *b);
int main()
{
//    freopen("data.txt","r",stdin);
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    memset(b,0,sizeof(b));
    int n;
    cin>>n;
    int i;
    for(i=0;i<2*n;i++)
    {
        scanf("%d",&a[i].number);
        a[i].x=i+1;
        b[a[i].number]+=1;
    }
//    qsort(a,2*n,sizeof(Dot),compare);
    sort(a,a+2*n,comp);
    if(!pairs()) printf("-1\n");
    else
    {
        for(i=0;i<n;i++)
        {
            printf("%d %d\n",a[2*i].x,a[2*i+1].x);
        }
    }
    return 0;
}

int compare(const void *a,const void *b)
{
    Dot *c=(Dot*)a, *d=(Dot*)b;
    if((c->number)-(d->number)>0) return 1;
    else if((c->number)-(d->number)==0) return 0;
    else return -1;
}

bool comp(const Dot &a,const Dot &b)
{
    return a.number<b.number;
}

bool pairs()
{
    int i,ok=1;
    for(i=1;i<=5000;i++)
    {
        if(b[i]%2)
        {
            ok=0;
            break;
        }
    }
    if(ok) return true;
    else return false;
}


#include<iostream>
#include<cstdlib>
#include<complex>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 3*100000 + 100
struct Dot
{
    int number;
    int x;
};
struct Dot a[MAXN];
int b[5000+50];
bool comp(const Dot &a,const Dot &b);
bool pairs();
int main()
{
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    memset(b,0,sizeof(b));
    int n;
    cin>>n;
    int i;
    for(i=0;i<2*n;i++)
    {
        scanf("%d",&a[i].number);
        a[i].x=i+1;
        b[a[i].number]+=1;
    }
    if(!pairs()) printf("-1\n");
    else
    {
        sort(a,a+2*n,comp);
        for(i=0;i<n;i++)
        {
            printf("%d %d\n",a[2*i].x,a[2*i+1].x);
        }
    }
    return 0;
}

bool comp(const Dot &a,const Dot &b)
{
    return a.number<b.number;
}

bool pairs()
{
    int i,ok=1;
    for(i=1;i<=5000;i++)
    {
        if(b[i]%2)
        {
            ok=0;
            break;
        }
    }
    if(ok) return true;
    else return false;
}


#include <cstdio>
#include <iostream>
#include <fstream>
#include <sstream>

int main(){
    FILE * inputFile = fopen("input.txt","r");
    if(inputFile){
        const int RANGE = 5000;
        long array[RANGE + 1] = {0};

        long n(0); fscanf(inputFile, "%ld\n", &n);
        long *firstGroup  = new long[n];
        long *secondGroup = new long[n];

        long index(0);
        long temp(0);

        for(long k = 0; k < 2 * n; k++){
            fscanf(inputFile, "%ld", &temp);
            if(array[temp] == 0){array[temp] = 1 + k;}
            else{
                firstGroup[index]  = array[temp];
                secondGroup[index] = 1 + k;
                array[temp] = 0;
                ++index;
            }
        }

        fclose(inputFile);

        FILE * outputFile = fopen("output.txt","w");
        if(index == n){for(long k = 0; k < n ; k++){fprintf(outputFile, "%ld %ld\n", firstGroup[k], secondGroup[k]);}}
        else{fputs("-1",outputFile);}
        fclose(outputFile);
    }

    return 0;
}


#include <cstdio>
#include <iostream>
#include <fstream>
#include <sstream>

int main(){
    FILE * inputFile = fopen("input.txt","r");
    if(inputFile){
        long n(0); fscanf(inputFile, "%ld\n", &n);
        long *array = new long[2 * n];
        for(long k = 0; k < 2 * n; k++){fscanf(inputFile, "%ld", array + k);}
        fclose(inputFile);

        long *firstGroup = new long[n];
        long *secondGroup = new long[n];

        bool paired(1);
        long first(0);

        for(long k = 0; k < n; k++){
            while(first < 2 * n - 1 && array[first] == 0){++first;}
            long second = first + 1;
            for(second = first + 1; second < 2 * n; second++){
               if(array[first] != 0 && array[first] == array[second]){
                    firstGroup[k]  = first + 1;
                    secondGroup[k] = second + 1;
                    array[first] = array[second] = 0;
                    break;
                }
            }
            if(second == 2 * n && array[second - 1] != 0){paired = 0; break;}
        }

        FILE * outputFile = fopen("output.txt","w");
        if(paired){for(long k = 0; k < n ; k++){fprintf(outputFile, "%ld %ld\n", firstGroup[k], secondGroup[k]);}}
        else{fputs("-1",outputFile);}
        fclose(outputFile);
    }

    return 0;
}


#include <cstdio>
#include <iostream>
#include <fstream>
#include <sstream>

int main(){
    FILE * inputFile = fopen("input.txt","r");
    if(inputFile){
        long n(0); fscanf(inputFile, "%ld\n", &n);
        long *array = new long[2 * n];
        for(long k = 0; k < 2 * n; k++){fscanf(inputFile, "%ld", array + k);}
        fclose(inputFile);

        long *firstGroup = new long[n];
        long *secondGroup = new long[n];

        long first(0);

        for(int k = 0; k < n; k++){
            while(first < 2 * n - 1 && array[first] == 0){++first;}
            for(long second = first + 1; second < 2 * n; second++){
               if(array[first] != 0 && array[first] == array[second]){
                    firstGroup[k]  = first + 1;
                    secondGroup[k] = second + 1;
                    array[first] = array[second] = 0;
                    break;
                }
            }
        }

        FILE * outputFile = fopen("output.txt","w");
        if(firstGroup[n - 1] != 0 && secondGroup[n - 1] != 0){for(int k = 0; k < n ; k++){fprintf(outputFile, "%ld %ld\n", firstGroup[k], secondGroup[k]);}}
        else{fputs("-1",outputFile);}
        fclose(outputFile);
    }

    return 0;
}


#include <cstdio>
#include <iostream>
#include <fstream>
#include <sstream>

int main(){
    FILE * inputFile = fopen("input.txt","r");
    if(inputFile){
        long n(0); fscanf(inputFile, "%ld\n", &n);
        long *array = new long[2 * n];
        for(long k = 0; k < 2 * n; k++){fscanf(inputFile, "%ld", array + k);}
        fclose(inputFile);

        long *firstGroup = new long[n];
        long *secondGroup = new long[n];

        long first(0);

        for(int k = 0; k < n; k++){
            while(first < 2 * n - 1 && array[first] == 0){++first;}
            long second = first + 1;
            for(second = first + 1; second < 2 * n; second++){
               if(array[first] != 0 && array[first] == array[second]){
                    firstGroup[k]  = first + 1;
                    secondGroup[k] = second + 1;
                    array[first] = array[second] = 0;
                    break;
                }
            }
            if(second == 2 * n - 1 && array[second] != 0){break;}
        }

        FILE * outputFile = fopen("output.txt","w");
        if(firstGroup[n - 1] != 0 && secondGroup[n - 1] != 0){for(int k = 0; k < n ; k++){fprintf(outputFile, "%ld %ld\n", firstGroup[k], secondGroup[k]);}}
        else{fputs("-1",outputFile);}
        fclose(outputFile);
    }

    return 0;
}


#include <cstdio>
#include <iostream>
#include <fstream>
#include <sstream>

int main(){
    FILE * inputFile = fopen("input.txt","r");
    if(inputFile){
        long n(0); fscanf(inputFile, "%ld\n", &n);
        long *array = new long[2 * n];
        for(long k = 0; k < 2 * n; k++){fscanf(inputFile, "%ld", array + k);}
        fclose(inputFile);

        long *firstGroup = new long[n];
        long *secondGroup = new long[n];

        bool paired(1);
        long first(0);

        for(int k = 0; k < n; k++){
            while(first < 2 * n - 1 && array[first] == 0){++first;}
            long second = first + 1;
            for(second = first + 1; second < 2 * n; second++){
               if(array[first] != 0 && array[first] == array[second]){
                    firstGroup[k]  = first + 1;
                    secondGroup[k] = second + 1;
                    array[first] = array[second] = 0;
                    break;
                }
            }
            if(second == 2 * n && array[second - 1] != 0){paired = 0; break;}
        }

        FILE * outputFile = fopen("output.txt","w");
        if(paired){for(int k = 0; k < n ; k++){fprintf(outputFile, "%ld %ld\n", firstGroup[k], secondGroup[k]);}}
        else{fputs("-1",outputFile);}
        fclose(outputFile);
    }

    return 0;
}


#include <cstdio>
#include <iostream>
#include <fstream>
#include <sstream>

int main(){
    FILE * inputFile = fopen("input.txt","r");
    if(inputFile){
        long n(0); fscanf(inputFile, "%ld\n", &n);
        long *array = new long[2 * n];
        for(long k = 0; k < 2 * n; k++){fscanf(inputFile, "%ld", array + k);}
        fclose(inputFile);

        long *firstGroup = new long[n];
        long *secondGroup = new long[n];

        long first(0);

        for(int k = 0; k < n; k++){
            while(first < 2 * n - 1 && array[first] == 0){++first;}
            for(long second = first + 1; second < 2 * n; second++){
               if(array[first] != 0 && array[first] == array[second]){
                    firstGroup[k]  = first + 1;
                    secondGroup[k] = second + 1;
                    array[first] = array[second] = 0;
                    break;
                }
            }
        }

        FILE * outputFile = fopen("output.txt","w");
        if(firstGroup[n - 1] != 0 && secondGroup[n - 1] != 0){
            for(int k = 0; k < n ; k++){
                fprintf(outputFile, "%ld %ld\n", firstGroup[k], secondGroup[k]);
                printf("%ld %ld\n", firstGroup[k], secondGroup[k]);
            }
        }
        else{fprintf(outputFile, "-1");}
        fclose(outputFile);

        }

    return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <utility>
#include <cassert>
#include <numeric>
#include <sstream>
using namespace std;

#define REQUIRE(cond, message) \
    do { \
        if (!(cond)) { \
            std::cerr << message << std::endl; \
            assert(false); \
        } \
    } while (false)

#define forn(i, n) for (int i = 0; i < int(n); ++i)
#define for1(i, n) for (int i = 1; i <= int(n); ++i)
#define forv(i, v) forn(i, v.size())
#define pb push_back
#define mp make_pair
#define all(v) v.begin(), v.end()

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef long long ll;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef vector<string> vs;
typedef long double ld;

const int INF = std::numeric_limits<int>::max();
const char* IN_FILE = ".in";
const char* OUT_FILE = ".out";

void solve()
{
    int n; cin >> n;
    n *= 2;
    vector<pii> a(n);
    forn(i, n) cin >> a[i].first, a[i].second = i;
    sort(all(a));
    vector<pii> ans;
    int l = 0;
    while (l < n) {
        if (a[l].first != a[l + 1].first) {
            cout << -1 << endl;
            return;
        }
        ans.pb(mp(a[l].second + 1, a[l + 1].second + 1));
        l += 2;
    }
    forn(i, n / 2) {
        cout << ans[i].first << " " << ans[i].second << endl;
    }
}

void init()
{
    freopen("input.txt", "rt", stdin);
    freopen("output.txt", "wt", stdout);
}

int main()
{
    ios_base::sync_with_stdio(false);
    init();
    solve();
    return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <utility>
#include <cassert>
#include <numeric>
#include <sstream>
using namespace std;

#define REQUIRE(cond, message) \
    do { \
        if (!(cond)) { \
            std::cerr << message << std::endl; \
            assert(false); \
        } \
    } while (false)

#define forn(i, n) for (int i = 0; i < int(n); ++i)
#define for1(i, n) for (int i = 1; i <= int(n); ++i)
#define forv(i, v) forn(i, v.size())
#define pb push_back
#define mp make_pair
#define all(v) v.begin(), v.end()

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef long long ll;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef vector<string> vs;
typedef long double ld;

const int INF = std::numeric_limits<int>::max();
const char* IN_FILE = ".in";
const char* OUT_FILE = ".out";

void solve()
{
    int n; cin >> n;
    n *= 2;
    vector<pii> a(n);
    forn(i, n) cin >> a[i].first, a[i].second = i;
    sort(all(a));
    vector<pii> ans;
    int l = 0;
    while (l < n) {
        if (a[l].first != a[l + 1].first) {
            cout << -1 << endl;
            return;
        }
        ans.pb(mp(a[l].second + 1, a[l + 1].second + 1));
        l += 2;
    }
    forn(i, n / 2) {
        cout << ans[i].first << " " << ans[i].second << endl;
    }
}

void init()
{
    freopen("input.txt", "rt", stdin);
    freopen("output.txt", "wt", stdout);
}

int main()
{
    ios_base::sync_with_stdio(false);
//    init();
    solve();
    return 0;
}


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

int main() {
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    int n;
    scanf("%d", &n);

    vector<pair<int, int> > a(2 * n);
    for (int i = 1; i <= 2 * n; ++i) {
        scanf("%d", &a[i - 1].first);
        a[i - 1].second = i;
    }

    sort(a.begin(), a.end());

    for (int i = 0; i < 2 * n; i += 2) {
        if (a[i].first != a[i + 1].first) {
            printf("-1\n");
            return 0;
        }
    }
    for (int i = 0; i < 2 * n; i += 2) {
        printf("%d %d\n", a[i].second, a[i + 1].second);
    }
    return 0;
}


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

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

    vector<pair<int, int> > a(2 * n);
    for (int i = 1; i <= 2 * n; ++i) {
        scanf("%d", &a[i - 1].first);
        a[i - 1].second = i;
    }

    sort(a.begin(), a.end());

    for (int i = 0; i < 2 * n; i += 2) {
        if (a[i].first != a[i + 1].first) {
            printf("-1\n");
            return 0;
        }
    }
    for (int i = 0; i < 2 * n; i += 2) {
        printf("%d %d\n", a[i].second, a[i + 1].second);
    }
    return 0;
}


#include <vector>
#include <map>
#include <iostream>
using namespace std;

int main() {
	int n, a;
	map<int, vector<int>> m;

	cin >> n;
	for (int i = 0; i < 2*n; ++i) {
		cin >> a;
		m[a].push_back(i);
	}

	for (auto j = m.begin(); j != m.end(); ++j) {
		if (j->second.size()&1) {
			cout << "-1";
			return 0;
		}
	}

	for (auto j = m.begin(); j != m.end(); ++j) {
		for (int i = 0; i < (int)j->second.size()/2; ++i) {
			cout << j->second[2*i] + 1 << " " << j->second[2*i + 1] + 1 << "\n";
		}
	}

	return 0;
}


#include <cstdio>
#include <vector>
#include <map>
#include <iostream>
using namespace std;

int main() {
	int n, a;
	map<int, vector<int>> m;

	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);

	cin >> n;
	for (int i = 0; i < 2*n; ++i) {
		cin >> a;
		m[a].push_back(i);
	}

	for (auto j = m.begin(); j != m.end(); ++j) {
		if (j->second.size()&1) {
			cout << "-1";
			return 0;
		}
	}

	for (auto j = m.begin(); j != m.end(); ++j) {
		for (int i = 0; i < (int)j->second.size()/2; ++i) {
			cout << j->second[2*i] + 1 << " " << j->second[2*i + 1] + 1 << "\n";
		}
	}

	return 0;
}


#include <functional>
#include <algorithm>
#include <iostream>
#include <numeric>
#include <stdio.h>
#include <string>
#include <vector>
#include <cctype>
#include <math.h>
#include <time.h>
#include <queue>
#include <stack>
#include <set>
#include <map>

using namespace std;

#define all(p) (p).begin(), (p).end()
#define fi first
#define se second

typedef long long ll;

const int N = 5555;
const int INF = int(1e9), mod = INF + 7;

vector <int> cards[N];

int main() {

    int n;
    scanf("%d", &n);

    for (int i = 0; i < 2 * n; ++i) {
        int x;
        scanf("%d", &x);

        cards[x].push_back(i + 1);
    }

    for (int i = 1; i < 5001; ++i) {
        if (cards[i].size() % 2) {
            puts("-1");
            return 0;
        }
    }

    for (int i = 1; i < 5001; ++i) {
        for (size_t it = 0; it < cards[i].size(); ++++it)
            printf("%d %d\n", cards[i][it], cards[i][it + 1]);
    }

    return 0;
}


#include <functional>
#include <algorithm>
#include <iostream>
#include <numeric>
#include <stdio.h>
#include <string>
#include <vector>
#include <cctype>
#include <math.h>
#include <time.h>
#include <queue>
#include <stack>
#include <set>
#include <map>

using namespace std;

#define all(p) (p).begin(), (p).end()
#define fi first
#define se second

typedef long long ll;

const int N = 5555;
const int INF = int(1e9), mod = INF + 7;

vector <int> cards[N];

int main() {

    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);

    int n;
    scanf("%d", &n);

    for (int i = 0; i < 2 * n; ++i) {
        int x;
        scanf("%d", &x);

        cards[x].push_back(i + 1);
    }

    for (int i = 1; i < 5001; ++i) {
        if (cards[i].size() % 2) {
            puts("-1");
            return 0;
        }
    }

    for (int i = 1; i < 5001; ++i) {
        for (size_t it = 0; it < cards[i].size(); it += 2)
            printf("%d %d\n", cards[i][it], cards[i][it + 1]);
    }

    return 0;
}


#include <functional>
#include <algorithm>
#include <iostream>
#include <numeric>
#include <stdio.h>
#include <string>
#include <vector>
#include <cctype>
#include <math.h>
#include <time.h>
#include <queue>
#include <stack>
#include <set>
#include <map>

using namespace std;

#define all(p) (p).begin(), (p).end()
#define fi first
#define se second

typedef long long ll;

const int N = 5555;
const int INF = int(1e9), mod = INF + 7;

vector <int> cards[N];

int main() {

    int n;
    scanf("%d", &n);

    for (int i = 0; i < 2 * n; ++i) {
        int x;
        scanf("%d", &x);

        cards[x].push_back(i + 1);
    }

    for (int i = 1; i < 5001; ++i) {
        if (cards[i].size() % 2) {
            puts("-1");
            return 0;
        }
    }

    for (int i = 1; i < 5001; ++i) {
        for (size_t it = 0; it < cards[i].size(); it += 2)
            printf("%d %d\n", cards[i][it], cards[i][it + 1]);
    }

    return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <cctype>
#include <ctime>

#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
#include <set>
#include <map>
#include <stack>
using namespace std;
typedef vector<int> vi;
#define SQR(x) ((x)*(x))
#define rep(i, n) for (int i=0; i<(n); ++i)
#define repf(i, a, b) for (int i=(a); i<=(b); ++i)
#define repd(i, a, b) for (int i=(a); i>=(b); --i)
#define pb push_back
#define sz(a) ((int)(a).size())
#define all(a) a.begin(), a.end()
#define mid(x, y) ((x+y)/2)
#define vp vector<P>
#define itr iterator
#define N 300000

struct P{
	int i, k;
	bool operator <(const P &p)const{
		return k<p.k;
	}
};

int i,j,k,m,n,l;
P a[N*2+10];

int main(){
	freopen("input.txt", "r", stdin);
   	freopen("output.txt", "w", stdout);
	while (~scanf("%d", &n)){
		rep(i, 2*n) scanf("%d", &a[i].k), a[i].i=i;
		sort(a, a+2*n);
		bool flag=true;
		rep(i, n) if (a[2*i].k!=a[2*i+1].k){
			flag=false; break;
		}
		if (flag){
			rep(i, n) printf("%d %d\n", a[i*2].i+1, a[i*2+1].i+1);
		}
		else puts("-1");
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <list>
#include <deque>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <map>
#include <utility>
using namespace std;

int main()
{
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    long long N;
    cin>>N;
    vector<pair<int,int>> v(N*2);
    for(long long i=0;i<N*2;++i)
    {
        cin>>v[i].first;
        v[i].second=i;
    }
    sort(v.begin(),v.end());
    bool f=false;
    for(long long i=0;i<N*2;i+=2)
    {
        if(v[i].first!=v[i+1].first)
        {
            f=true;
            break;
        }
    }
        if(f)
            cout<<-1<<endl;
        else
            for(long long i=0;i<N*2;i+=2)
                cout<<v[i].second+1<<' '<<v[i+1].second+1<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <algorithm>
#include <set>
#include <cstdio>
#include <string.h>
#include <limits>
#include <sstream>
using namespace std;

int main(){
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
  int n, a;
  cin>>n;
  vector<int> cards(5001, 0), v;
  vector<vector<int> > G(5001);
  for(int i = 0; i < 2 * n; ++i){
    cin>>a;
    v.push_back(i);
    cards[a]++;
    G[a].push_back(i + 1);
  }
  for(int i = 0; i < 5001; ++i){
    if(cards[i] % 2 != 0){
      cout<<-1<<endl;
      return 0;
    }
  }
  for(int i = 0; i < G.size(); ++i){
    if(G[i].size()!=0){
      for(int j = 0; j < G[i].size(); j+=2){
	  cout<<G[i][j]<<" "<<G[i][j + 1]<<endl;
	}

      }}

  return 0;
}


#include <cstdio>
#include <algorithm>
using namespace std;

const int MN = 600005;
int n, a[MN], id[MN];

void SWAP(int i, int j) {
     swap(a[i], a[j]);
     swap(id[i], id[j]);
}

void QICK_SORT(int first, int last) {
     if (first >= last) return;
     int i = first, j = last, m = a[(i + j)/2];
     while (i <= j) {
           while (a[i] < m) i++;
           while (a[j] > m) j--;
           if (i <= j) {
              SWAP(i, j);
              i++; j--;
           }
     }
     if (first < j) QICK_SORT(first, j);
     if (i < last) QICK_SORT(i, last);
}

int main() {
    freopen("output.txt", "w", stdout);
    freopen("input.txt", "r", stdin);
    scanf("%d", &n);
    n *= 2;
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        id[i] = i;
    }

    QICK_SORT(1, n);

    int temp =  n - 1;
    for (int i = 1; i <= temp; i += 2)
        if (a[i] != a[i+1]) {
           printf("-1\n");
           return 0;
        }

    for (int i = 1; i <= temp; i += 2)
        printf("%d %d\n", id[i], id[i+1]);
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <set>
using namespace std;

const int MN = 5001;
int n, Size[MN];
int a[MN][MN];
set<int> f;
set<int> :: iterator it;

int main() {
    scanf("%d", &n);
    n *= 2;
    int temp, Max = 0;
    for (int i = 1; i <= n; i++) {
        scanf("%d", &temp);
        a[temp][Size[temp]++] = i;
        f.insert(temp);
    }

    for (it = f.begin(); it != f.end(); it++)
        if (Size[*it] % 2) {
           printf("-1");
           return 0;
        }

    for (it = f.begin(); it != f.end(); it++) {
           temp = Size[*it] - 1;
           for (int j = 0; j < temp; j += 2)
               printf("%d %d\n", a[*it][j], a[*it][j+1]);
        }
    //system("pause");
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;

const int MN = 50001;
int n, Size[MN];
vector <int> a[MN];
vector <int>::iterator it;

int main() {
    scanf("%d", &n);
    n *= 2;
    int temp, Max = 0;
    for (int i = 1; i <= n; i++) {
        scanf("%d", &temp);
        a[temp].push_back(i);
        if (Max < temp) Max = temp;
    }

    for (int i = 1; i <= Max; i++)
        if (a[i].size() % 2) {
           printf("-1");
           return 0;
        }

    for (int i = 1; i <= Max; i++)
        if (a[i].size()) {
           temp = a[i].size() - 1;
           for (int j = 0; j < temp; j += 2)
               printf("%d %d\n", a[i][j], a[i][j+1]);
        }
    //system("pause");
    return 0;
}


#include <cstdio>
#include <algorithm>
using namespace std;

const int MN = 600005;
int n, a[MN], id[MN];

void SWAP(int i, int j) {
     swap(a[i], a[j]);
     swap(id[i], id[j]);
}

void QICK_SORT(int first, int last) {
     if (first >= last) return;
     int i = first, j = last, m = a[(i + j)/2];
     while (i <= j) {
           while (a[i] < m) i++;
           while (a[j] > m) j--;
           if (i <= j) {
              SWAP(i, j);
              i++; j--;
           }
     }
     if (first < j) QICK_SORT(first, j);
     if (i < last) QICK_SORT(i, last);
}

int main() {
    scanf("%d", &n);
    n *= 2;
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        id[i] = i;
    }

    QICK_SORT(1, n);

    int temp =  n - 1;
    for (int i = 1; i <= temp; i += 2)
        if (a[i] != a[i+1]) {
           printf("-1");
           //system("pause");
           return 0;
        }

    for (int i = 1; i <= temp; i += 2)
        printf("%d %d\n", id[i], id[i+1]);
    //system("pause");
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <set>
using namespace std;

const int MN = 5001;
int n, Size[MN];
int a[MN][15000];
set<int> f;
set<int> :: iterator it;

int main() {
    scanf("%d", &n);
    n *= 2;
    int temp, Max = 0;
    for (int i = 1; i <= n; i++) {
        scanf("%d", &temp);
        a[temp][Size[temp]++] = i;
        f.insert(temp);
    }

    for (it = f.begin(); it != f.end(); it++)
        if (Size[*it] % 2) {
           printf("-1");
           return 0;
        }

    for (it = f.begin(); it != f.end(); it++) {
           temp = Size[*it] - 1;
           for (int j = 0; j < temp; j += 2)
               printf("%d %d\n", a[*it][j], a[*it][j+1]);
        }
    //system("pause");
    return 0;
}


#include <cstdio>
#include <algorithm>
using namespace std;

const int MN = 600005;
int n, a[MN], id[MN];

void SWAP(int i, int j) {
     swap(a[i], a[j]);
     swap(id[i], id[j]);
}

void QICK_SORT(int first, int last) {
     if (first >= last) return;
     int i = first, j = last, m = a[(i + j)/2];
     while (i <= j) {
           while (a[i] < m) i++;
           while (a[j] > m) j--;
           if (i <= j) {
              SWAP(i, j);
              i++; j--;
           }
     }
     if (first < j) QICK_SORT(first, j);
     if (i < last) QICK_SORT(i, last);
}

int main() {
    scanf("%d", &n);
    n *= 2;
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        id[i] = i;
    }

    QICK_SORT(1, n);

    int temp =  n - 1;
    for (int i = 1; i <= temp; i += 2)
        if (a[i] != a[i+1]) {
           printf("-1\n");
           return 0;
        }

    for (int i = 1; i <= temp; i += 2)
        printf("%d %d\n", id[i], id[i+1]);
    return 0;
}


#include <iostream>

int big=0;

int log4roof(int num){
  int k;
  for(k=0;(1<<(k*2))<num;k++);
  return k;
}

int main(){
  int N;
  std::cin>>N;
  for(int i=0;i<N;i++){
    int K,A;
    std::cin>>K>>A;
    if(A>1){
      big=std::max(big,K+log4roof(A));
    }else{
      big=std::max(big,K+1);
    }
  }
  std::cout<<big<<std::endl;
  return 0;
}


#include <iostream>

int big=0;

int log4roof(int num){
  int k;
  for(k=0;(1<<(k*2))<num;k++);
  return k;
}

int main(){
  int N;
  std::cin>>N;
  for(int i=0;i<N;i++){
    int K,A;
    std::cin>>K>>A;
    big=std::max(big,K+log4roof(A));
  }
  std::cout<<big<<std::endl;
  return 0;
}


#include <bits/stdc++.h>

#define FOR(i,a,b) for( int i = (a); i < (int)(b); i++ )
#define REP(i,n) FOR(i,0,n)
#define YYS(x,arr) for(auto& x:arr)
#define ALL(x) (x).begin(),(x).end()
#define SORT(x) sort( (x).begin(),(x).end() )
#define REVERSE(x) reverse( (x).begin(),(x).end() )
#define pb emplace_back
#define mp make_pair
#define fi first
#define se second

using namespace std;

typedef long double ld;
typedef long long int ll;
typedef pair<int,int> pi;
typedef pair<ll,ll> pl;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<bool> vb;
typedef vector<ld> vd;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<vpl> gr;
typedef vector<vi> mi;
typedef vector<vl> ml;
typedef vector<vd> md;

const int INF = 1e9+10;
const ll INFLL = 1e18+10;
const ld EPS = 1e-8;
const ld EPSLD = 1e-14;
const ll MOD = 1000000007;

template<class T> T &chmin( T &a , const T &b ){ return a = min(a,b); }
template<class T> T &chmax( T &a , const T &b ){ return a = max(a,b); }

const int MAX_N = 100010;

int n;
pl b[MAX_N];

ll size;
ll cnt;

ll e[64];

int main(){

  scanf( "%d" , &n );
  REP( i , n ) scanf( "%lld %lld" , &b[i].fi , &b[i].se );
  sort( b , b+n );

  e[0] = 1;
  FOR( i , 1 , 30 ) e[i] = e[i-1] * 4;

  size = b[0].fi;
  cnt = b[0].se;

  FOR( i , 1 , n ){
    if( b[i].fi - size >= 30 ) cnt = 1;
    else cnt = (cnt-1) / e[ b[i].fi - size ] + 1;
    chmax( cnt , b[i].se );
    size = b[i].fi;
  }

  if( cnt == 1 ) size++;
  while( cnt > 1 ) size++, cnt = (cnt-1)/4 + 1;

  cout << size << endl;

  return 0;
}


#include <bits/stdc++.h>

#define FOR(i,a,b) for( int i = (a); i < (int)(b); i++ )
#define REP(i,n) FOR(i,0,n)
#define YYS(x,arr) for(auto& x:arr)
#define ALL(x) (x).begin(),(x).end()
#define SORT(x) sort( (x).begin(),(x).end() )
#define REVERSE(x) reverse( (x).begin(),(x).end() )
#define pb emplace_back
#define mp make_pair
#define fi first
#define se second

using namespace std;

typedef long double ld;
typedef long long int ll;
typedef pair<int,int> pi;
typedef pair<ll,ll> pl;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<bool> vb;
typedef vector<ld> vd;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<vpl> gr;
typedef vector<vi> mi;
typedef vector<vl> ml;
typedef vector<vd> md;

const int INF = 1e9+10;
const ll INFLL = 1e18+10;
const ld EPS = 1e-8;
const ld EPSLD = 1e-14;
const ll MOD = 1000000007;

template<class T> T &chmin( T &a , const T &b ){ return a = min(a,b); }
template<class T> T &chmax( T &a , const T &b ){ return a = max(a,b); }

const int MAX_N = 100010;

int n;
pl b[MAX_N];

ll size;
ll cnt;

ll e[64];

int main(){

  scanf( "%d" , &n );
  REP( i , n ) scanf( "%lld %lld" , &b[i].fi , &b[i].se );
  sort( b , b+n );

  e[0] = 1;
  FOR( i , 1 , 30 ) e[i] = e[i-1] * 4;

  size = b[0].fi;
  cnt = b[0].se;

  FOR( i , 1 , n ){
    if( b[i].fi - size >= 30 ) cnt = 1;
    else cnt = (cnt-1) / e[ b[i].fi - size ] + 1;
    chmax( cnt , b[i].se );
    size = b[i].fi;
  }

  while( cnt > 1 ) size++, cnt = (cnt-1)/4 + 1;

  cout << size << endl;

  return 0;
}


#include <bits/stdc++.h>
#define ll  long long
#define MP make_pair
#define PB push_back
#define N 100009
#define MOD 1000000007
#define f  first
#define s  second
#define wt(x) cout << # x <<" = " << x << endl
#define FASTIO ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define inf 1e15

using namespace std;
void read(ll a= 0 )
{freopen("in","r",stdin);       if (a)  freopen("out","w",stdout); }
pair < ll , ll > p [N];
#define MAX 1000000009
int main ()
{
    FASTIO;
    ll n ;
    cin >> n ;
    for (int i =0  ; i < n ; i ++ )
        cin >> p[i] .f >> p[i].s ;
    sort ( p , p + n );
    reverse (p , p + n  );
    vector < ll > v ;
    for (int i =0  ; i < min ( (ll )20, n ) ; i ++ )
        v.PB (p[i].s);

    ll ans = p[0].f + 1 ;
    ll timer = 1;
    ll sum = timer;
    while (1)
    {
        bool done = 1 ;
    for (int i =0   ; i < v.size () ; i ++ )
    { if (sum > MAX) break ;
        sum *= 4 ;
        done &= sum >= v[i] ;

    }
        if  ( done ) return cout << ans , 0 ;
        timer *= 4 ;

        sum =  timer ;
        ans ++ ;
    }

}


#include <bits/stdc++.h>
#define ll  unsigned long long
#define MP make_pair
#define PB push_back
#define N 100009
#define MOD 1000000007
#define f  first
#define s  second
#define wt(x) cout << # x <<" = " << x << endl
#define FASTIO ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define inf 1e15

using namespace std;
void read(ll a= 0 )
{freopen("in","r",stdin);       if (a)  freopen("out","w",stdout); }
pair < ll , ll > p [N];
#define MAX 1000000009
int main ()
{
    FASTIO;
    ll n ;
    cin >> n ;
    for (int i =0  ; i < n ; i ++ )
        cin >> p[i] .f >> p[i].s ;
    sort ( p , p + n );
    reverse (p , p + n  );
    vector < ll > v ;
    v.PB(p[0].s);
    ll last ;
    last = p[0].f ;
    for (int i =1  ; i < min ( (ll )16, n ) &&v.size () < 16; i ++ )
    { while (last-1 != p[i].f&&v.size () < 16)v.PB(0) , last --;
    if  ( v.size() == 16)break;
        v.PB (p[i].s);
        last -- ;
    }

    ll ans = p[0].f + 1 ;
    ll timer = 1;
    ll sum = timer;
    while (1)
    {
        bool done = 1 ;
    for (int i =0   ; i < v.size () ; i ++ )
    { if (sum > MAX) break ;
        sum *= 4 ;
        done &= sum >= v[i] ;

    }
        if  ( done ) return cout << ans , 0 ;
        timer *= 4 ;

        sum =  timer ;
        ans ++ ;
    }

}


#include <bits/stdc++.h>
#define ll unsigned long long
#define MP make_pair
#define PB push_back
#define N 100009
#define MOD 1000000007
#define f  first
#define s  second
#define wt(x) cout << # x <<" = " << x << endl
#define FASTIO ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define inf 1e15

using namespace std;
void read(ll a= 0 )
{freopen("in","r",stdin);       if (a)  freopen("out","w",stdout); }
pair < ll , ll > p [N];
#define MAX 1000000009
int main ()
{
    FASTIO;
    ll n ;
    cin >> n ;
    for (int i =0  ; i < n ; i ++ )
        cin >> p[i] .f >> p[i].s ;
    sort ( p , p + n );
    reverse (p , p + n  );
    vector < ll > v ;
    for (int i =0  ; i < min ( (ll )20, n ) ; i ++ )
        v.PB (p[i].s);

    ll ans = p[0].f + 1 ;
    ll timer = 1;
    ll sum = timer;
    while (1)
    {
        bool done = 1 ;
    for (int i =0   ; i < v.size () ; i ++ )
    { if (sum > MAX) break ;
        sum *= 4 ;
        done &= sum >= v[i] ;

    }
        if  ( done ) return cout << ans , 0 ;
        timer *= 4 ;

        sum =  timer ;
        ans ++ ;
    }

}


#include <bits/stdc++.h>
#define ll  unsigned long long
#define MP make_pair
#define PB push_back
#define N 100009
#define MOD 1000000007
#define f  first
#define s  second
#define wt(x) cout << # x <<" = " << x << endl
#define FASTIO ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define inf 1e15

using namespace std;
void read(ll a= 0 )
{freopen("in","r",stdin);       if (a)  freopen("out","w",stdout); }
pair < ll , ll > p [N];
#define MAX 1000000009
int main ()
{
    FASTIO;
    ll n ;
    cin >> n ;
    for (int i =0  ; i < n ; i ++ )
        cin >> p[i] .f >> p[i].s ;
    sort ( p , p + n );
    reverse (p , p + n  );
    vector < ll > v ;
    for (int i =0  ; i < min ( (ll )33, n ) ; i ++ )
        v.PB (p[i].s);

    ll ans = p[0].f + 1 ;
    ll timer = 1;
    ll sum = timer;
    while (1)
    {
        bool done = 1 ;
    for (int i =0   ; i < v.size () ; i ++ )
    { if (sum > MAX) break ;
        sum *= 4 ;
        done &= sum >= v[i] ;

    }
        if  ( done ) return cout << ans , 0 ;
        timer *= 4 ;

        sum =  timer ;
        ans ++ ;
    }

}


#include <bits/stdc++.h>
#define ll  unsigned long long
#define MP make_pair
#define PB push_back
#define N 100009
#define MOD 1000000007
#define f  first
#define s  second
#define wt(x) cout << # x <<" = " << x << endl
#define FASTIO ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define inf 1e15

using namespace std;
void read(ll a= 0 )
{freopen("in","r",stdin);       if (a)  freopen("out","w",stdout); }
pair < ll , ll > p [N];
#define MAX 1000000009
int main ()
{
    FASTIO;
    ll n ;
    cin >> n ;
    for (int i =0  ; i < n ; i ++ )
        cin >> p[i] .f >> p[i].s ;
    sort ( p , p + n );
    reverse (p , p + n  );
    vector < ll > v ;
    for (int i =0  ; i < min ( (ll )30, n ) ; i ++ )
        v.PB (p[i].s);

    ll ans = p[0].f + 1 ;
    ll timer = 1;
    ll sum = timer;
    while (1)
    {
        bool done = 1 ;
    for (int i =0   ; i < v.size () ; i ++ )
    { if (sum > MAX) break ;
        sum *= 4 ;
        done &= sum >= v[i] ;

    }
        if  ( done ) return cout << ans , 0 ;
        timer *= 4 ;

        sum =  timer ;
        ans ++ ;
    }

}


#include <bits/stdc++.h>
#define ll unsigned long long
#define MP make_pair
#define PB push_back
#define N 100009
#define MOD 1000000007
#define f  first
#define s  second
#define wt(x) cout << # x <<" = " << x << endl
#define FASTIO ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define inf 1e15

using namespace std;
void read(ll a= 0 )
{freopen("in","r",stdin);       if (a)  freopen("out","w",stdout); }
pair < ll , ll > p [N];

int main ()
{
    FASTIO;
    ll n ;
    cin >> n ;
    for (int i =0  ; i < n ; i ++ )
        cin >> p[i] .f >> p[i].s ;
    sort ( p , p + n );
    reverse (p , p + n  );
    vector < ll > v ;
    for (int i =0  ; i < min ( (ll )14, n ) ; i ++ )
        v.PB (p[i].s);

    ll ans = p[0].f + 1 ;
    ll timer = 1;
    ll sum = timer;
    while (1)
    {
        bool done = 1 ;
    for (int i =0   ; i < v.size () ; i ++ )
    {
        sum *= 4 ;
        done &= sum >= v[i] ;
    }
        if  ( done ) return cout << ans , 0 ;
        timer *= 4 ;
        sum =  timer ;
        ans ++ ;
    }

}


#include <bits/stdc++.h>
#define ll unsigned long long
#define MP make_pair
#define PB push_back
#define N 100009
#define MOD 1000000007
#define f  first
#define s  second
#define wt(x) cout << # x <<" = " << x << endl
#define FASTIO ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define inf 1e15

using namespace std;
void read(ll a= 0 )
{freopen("in","r",stdin);       if (a)  freopen("out","w",stdout); }
pair < ll , ll > p [N];

int main ()
{
    FASTIO;
    ll n ;
    cin >> n ;
    for (int i =0  ; i < n ; i ++ )
        cin >> p[i] .f >> p[i].s ;
    sort ( p , p + n );
    reverse (p , p + n  );
    vector < ll > v ;
    for (int i =0  ; i < min ( (ll )15, n ) ; i ++ )
        v.PB (p[i].s);

    ll ans = p[0].f + 1 ;
    ll timer = 1;
    ll sum = timer;
    while (1)
    {
        bool done = 1 ;
    for (int i =0   ; i < v.size () ; i ++ )
    {
        sum *= 4 ;
        done &= sum >= v[i] ;
    }
        if  ( done ) return cout << ans , 0 ;
        timer *= 4 ;
        sum =  timer ;
        ans ++ ;
    }

}


#include <iostream>
#include <map>
#include <algorithm>

using namespace std;

int main() {
    int n; cin >> n;
    int k, m;

    map <int, int> box;
    while(n--) {
        cin >> k >> m;
        box[k] = m;
    }

    auto i = box.begin();
    int l = i -> first, r = i -> second;
    ++i;

    while(i != box.end()) {
        int rx = i -> first - l;
        for(int i = 0; i < rx && r > 1; ++i) {
            bool t = r % 4;
            r >>= 2;
            r += t;
        }

        r = max(r, i -> second);
        l = i -> first;

        ++i;
    }

    while(r > 1) {
        l += 1;
        bool t = r % 4;
        r >>= 2;
        r += t;
    }

    cout << l;

    return 0;
}


#include <iostream>
#include <map>
#include <algorithm>

using namespace std;

int main() {
    int n; cin >> n;
    int k, m;

    map <int, int> box;
    while(n--) {
        cin >> k >> m;
        box[k] = m;
    }

    auto i = box.begin();
    int l = i -> first, r = i -> second;
    ++i;

    while(i != box.end()) {
        int rx = i -> first - l;
        for(int i = 0; i < rx && r > 1; ++i) {
            bool t = r % 4;
            r >>= 2;
            r += t;
        }

        r = max(r, i -> second);
        l = i -> first;

        ++i;
    }

    do {
        l += 1;
        bool t = r % 4;
        r >>= 2;
        r += t;
    } while(r > 1);

    cout << l;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define N 100100

typedef long long LL;

int n, a[N];
LL b[N];

int main() {
	scanf("%d", &n);
	for(int i = 1; i <= n; i ++) {
		scanf("%d%I64d", a + i, b + i);
	}
    int rt = 0, cur = -1;
    LL tp = 0;
    for(int i = 1; i <= n; i ++) {
    	b[i] = (b[i] + 3) >> 2;
    	a[i] ++;
    	while(b[i] > 1) {
    		b[i] = (b[i] + 3) >> 2;
			a[i] ++;
    	}
    	rt = max(rt, a[i]);
    }
	cout << rt << endl;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define N 100100

typedef long long LL;

int n, a[N], id[N];
LL b[N];

bool cmp(int i, int j) { return a[i] < a[j]; }

int main() {
	scanf("%d", &n);
	for(int i = 1; i <= n; i ++) {
		scanf("%d%I64d", a + i, b + i);
		id[i] = i;
	}
	sort(id + 1, id + n + 1, cmp);
    int rt = 0, cur = -1;
    LL tp = 0;
    a[0] = -1;
	for(int i = 1; i <= n + 1; i ++) {
        int j = id[i];
		if(cur == a[j]) tp += b[j];
		else {
			if(cur != -1) {
				int k = cur;
				LL tt = tp;
				while(tt > 1LL) {
					k ++;
					tt = (tt + 3) >> 2;
				}
				rt = max(rt, k);
			}
			tp = b[j];
			cur = a[j];
		}
	}
	cout << rt << endl;
	return 0;
}


#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
#define int long long
#define ll long long
#define ld long double
#define pb push_back
#define mp make_pair
#define endl '\n'
#define D(x) cout<<#x<<" -> "<<x<<'\n'
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define uni(x) (x).erase(unique(all(x)), (x).end());
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define rep1(i, n) for (int i = 1; i <= (int)(n); ++i)
const ll infll = powl(2, 62)-1;
const ld pi = 4.0*atanl(1.0);
const int mod = powl(10, 9) + 7;

int32_t main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);//freopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);
    int n;
    cin>>n;
    vector<pair<int, int> > arr(n);//size: 2^first, quantity
    rep(i,n) cin >> arr[i].first >> arr[i].second;
    int ans = 0;
    rep(i,n) {
        int size = arr[i].second, counter = 0, prod = 1;
        while(size > prod) {
            counter++;
            prod*=4;
        }
        ans = max(ans, arr[i].first + counter);
    }
    cout<<ans<<'\n';
    return 0;
}


#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
#define int long long
#define ll long long
#define ld long double
#define pb push_back
#define mp make_pair
#define endl '\n'
#define D(x) cout<<#x<<" -> "<<x<<'\n'
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define uni(x) (x).erase(unique(all(x)), (x).end());
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define rep1(i, n) for (int i = 1; i <= (int)(n); ++i)
const ll infll = powl(2, 62)-1;
const ld pi = 4.0*atanl(1.0);
const int mod = powl(10, 9) + 7;

int32_t main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);//freopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);
    int n;
    cin>>n;
    vector<pair<int, int> > arr(n);//size: 2^first, quantity
    rep(i,n) cin >> arr[i].first >> arr[i].second;
    int ans = 1;
    rep(i,n) {
        int size = arr[i].second, counter = 0, prod = 1;
        while(size > prod) {
            counter++;
            prod*=4;
        }
        ans = max(ans, arr[i].first + counter);
    }
    cout<<ans<<'\n';
    return 0;
}


#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
#define int long long
#define ll long long
#define ld long double
#define pb push_back
#define mp make_pair
#define endl '\n'
#define D(x) cout<<#x<<" -> "<<x<<'\n'
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define uni(x) (x).erase(unique(all(x)), (x).end());
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define rep1(i, n) for (int i = 1; i <= (int)(n); ++i)
const ll infll = powl(2, 62)-1;
const ld pi = 4.0*atanl(1.0);
const int mod = powl(10, 9) + 7;

int32_t main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);//freopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);
    int n;
    cin>>n;
    vector<pair<int, int> > arr(n);//size: 2^first, quantity
    rep(i,n) cin >> arr[i].first >> arr[i].second;
    int ans = 0;
    rep(i,n) {
        int amount = arr[i].second, counter = 1, prod = 4;
        while(amount > prod) {
            counter++;
            prod*=4;
        }
        ans = max(ans, arr[i].first + counter);
    }
    cout<<ans<<'\n';
    return 0;
}


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

namespace HABIT{
    #define f(a,b,c,d) for(register int a=b,c=d;a<=c;a++)
    #define g(a,b,c,d) for(register int a=b,c=d;a>=c;a--)
    #define LOCAL
    typedef int i32;
    typedef unsigned int u32;
    typedef long long int i64;
    typedef unsigned long long int u64;
    typedef pair<i64,i64> pii;
    const i32 MAXN=1e5+10;
    typedef i64 ar[MAXN];

    template<typename T> inline T Max(T a) { return a; }
    template<typename T,typename... Args> inline T Max(T a,Args... args){
        T b=Max(args...);
        return (a>b)?a:b;
    }
    template<typename T> inline T Min(T a) { return a; }
    template<typename T,typename... Args> inline T Min(T a,Args... args){
        T b=Min(args...);
        return (a<b)?a:b;
    }

    #ifdef LOCAL
        inline char gc() { return getchar(); }
    #else
        inline char gc() {
            static char s[1<<20|1]={0},*p1=s,*p2=s;
            return (p1==p2)&&(p2=(p1=s)+fread(s,1,1<<20,stdin),p1==p2)?EOF:*(p1++);
        }
    #endif
    inline i64 read(){
        register i64 ans=0;register char c=gc();register bool neg=0;
        while(c<48||c>57) neg^=!(c^'-'),c=gc();
        while(c>=48&&c<=57) ans=(ans<<3)+(ans<<1)+(c^48),c=gc();
        return neg?-ans:ans;
    }

    char Output_Ans[1<<20|1],*Output_Cur=Output_Ans;
    inline void output() { Output_Cur-=fwrite(Output_Ans,1,Output_Cur-Output_Ans,stdout); }
    inline void print(char c){
        if(Output_Cur-Output_Ans+1>>20) output();
        *(Output_Cur++)=c;
    }
    inline void print(char *s) { while(*s) print( *(s++) ); }
    inline void print(u64 x){
        if(!x) { print('0'); return ; }
        char buf[30]={0},*p=buf+28;
        while(x) *(p--)=x%10+48,x/=10;
        print(p+1);
    }
    inline void print(u32 x) { print( (u64)x ); }
    inline void print(i64 x){
        if(x<0) print('-'),x=-x;
        print( (u64)x );
    }
    inline void print(i32 x){
        if(x<0) print('-'),x=-x;
        print( (u64)x );
    }
}
using namespace HABIT;

pii Box[MAXN];
int main(){
    i32 N=read(),P,C=1;
    f(i,1,I,N) Box[i].first=read(),Box[i].second=read();
    sort(Box+1,Box+1+N);
    P=Box[N].first;
    f(i,1,I,N){
        i32 Tmp=Box[i].second;
        f(j,Box[i].first+1,J,Box[i+1].first) Tmp=Tmp+3>>2;
        Box[i+1].second=Max(Box[i+1].second,Tmp);
    }
    if(Box[N].second==1) P++;
    else{
        while(C<Box[N].second){
            P++;
            C<<=2;
        }
    }
    print(P);
    output();
    return 0;
}


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

namespace HABIT{
    #define f(a,b,c,d) for(register int a=b,c=d;a<=c;a++)
    #define g(a,b,c,d) for(register int a=b,c=d;a>=c;a--)
    #define LOCAL
    typedef int i32;
    typedef unsigned int u32;
    typedef long long int i64;
    typedef unsigned long long int u64;
    typedef pair<i64,i64> pii;
    const i32 MAXN=1e5+10;
    typedef i64 ar[MAXN];

    template<typename T> inline T Max(T a) { return a; }
    template<typename T,typename... Args> inline T Max(T a,Args... args){
        T b=Max(args...);
        return (a>b)?a:b;
    }
    template<typename T> inline T Min(T a) { return a; }
    template<typename T,typename... Args> inline T Min(T a,Args... args){
        T b=Min(args...);
        return (a<b)?a:b;
    }

    #ifdef LOCAL
        inline char gc() { return getchar(); }
    #else
        inline char gc() {
            static char s[1<<20|1]={0},*p1=s,*p2=s;
            return (p1==p2)&&(p2=(p1=s)+fread(s,1,1<<20,stdin),p1==p2)?EOF:*(p1++);
        }
    #endif
    inline i64 read(){
        register i64 ans=0;register char c=gc();register bool neg=0;
        while(c<48||c>57) neg^=!(c^'-'),c=gc();
        while(c>=48&&c<=57) ans=(ans<<3)+(ans<<1)+(c^48),c=gc();
        return neg?-ans:ans;
    }

    char Output_Ans[1<<20|1],*Output_Cur=Output_Ans;
    inline void output() { Output_Cur-=fwrite(Output_Ans,1,Output_Cur-Output_Ans,stdout); }
    inline void print(char c){
        if(Output_Cur-Output_Ans+1>>20) output();
        *(Output_Cur++)=c;
    }
    inline void print(char *s) { while(*s) print( *(s++) ); }
    inline void print(u64 x){
        if(!x) { print('0'); return ; }
        char buf[30]={0},*p=buf+28;
        while(x) *(p--)=x%10+48,x/=10;
        print(p+1);
    }
    inline void print(u32 x) { print( (u64)x ); }
    inline void print(i64 x){
        if(x<0) print('-'),x=-x;
        print( (u64)x );
    }
    inline void print(i32 x){
        if(x<0) print('-'),x=-x;
        print( (u64)x );
    }
}
using namespace HABIT;

pii Box[MAXN];
int main(){
    i32 N=read(),P,C=1;
    f(i,1,I,N) Box[i].first=read(),Box[i].second=read();
    sort(Box+1,Box+1+N);
    P=Box[N].first;
    f(i,1,I,N){
        i32 Tmp=Box[i].second;
        f(j,Box[i].first+1,J,Box[i+1].first) Tmp=Tmp+3>>2;
        Box[i+1].second=Max(Box[i+1].second,Tmp);
    }
    while(C<Box[N].second){
        P++;
        C<<=2;
    }
    print(P);
    output();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
 typedef pair<int,int> pii;
 typedef pair<char,char> pcc;
 typedef long long ll;
 typedef unsigned long long ull;
 typedef pair<ll,ll> pll;
typedef vector<ll> vll;
typedef vector<ull> vull;
typedef vector<int> vi;
typedef vector<bool> vb;
typedef tuple<int,int,int> tiii;
#define mod 1000000007LL
#define mx9 1000000000LL
#define mx10 10000000000LL
#define mx5 100000
#define mx8 100000000LL
#define mx7 10000000LL
#define mx6 1000000LL
#define mx6_5 5000000
#define last 4444444444
 #define f first
 #define s second
 #define rep(i,a,b) for(ll i=(a);i<=(b);i++)
#define reprev(i,a,b) for(ll i=(a);i>=(b);i--)
 #define repi(i,a,b) for(int i=(a);i<=(b);i++)
#define reprevi(i,a,b) for(int i=(a);i>=(b);i--)
#define mp make_pair
#define pb push_back
#define x first
#define y second
//#define PI 3.14159265
const long double PI = 2*acos(0.0);

typedef vector<bool> vb;
void print(vi &a)
{

    for(int i:a)
    {
        cout<<i<<" ";
    }
    cout<<"\n";
}
void print(vll &a)
{

    for(ll i:a)
    {
        cout<<i<<" ";
    }
    cout<<"\n";
}
void print(vector<long double> &a)
{

    for(long double i:a)
    {
        cout<<i<<" ";
    }
    cout<<"\n";
}
void print(vector<pll> &a)
{

    for(pll i:a)
    {
        cout<<i.f<<" "<<i.s<<"\n";
    }
    cout<<"\n";
}
ll dist_sq(pll a,pll b)
{
    return ((a.x-b.x)*(a.x-b.x)+ (a.y-b.y)*(a.y-b.y));
}

ll po(ll a,ll b)
{
    if(b<=0)
        return 1;
    else if(b==1)
        return a;

    ll vl = po((a*a),b/2);
    if(b%2==0)
        return vl;
    else
        return (vl)*a;
}

int main(void)
{
    ios_base::sync_with_stdio(false);
    int n;
    cin>>n;
    vector<pll> v(n);
    ll mx = 1;
    rep(i,0,n-1)
    {
        cin>>v[i].f>>v[i].s;
        mx = max(v[i].f + (ll)ceil(log2(v[i].s)/2.0),mx);

    }
    cout<<mx;
    //sort(v.begin(),v.end());

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
 typedef pair<int,int> pii;
 typedef pair<char,char> pcc;
 typedef long long ll;
 typedef unsigned long long ull;
 typedef pair<ll,ll> pll;
typedef vector<ll> vll;
typedef vector<ull> vull;
typedef vector<int> vi;
typedef vector<bool> vb;
typedef tuple<int,int,int> tiii;
#define mod 1000000007LL
#define mx9 1000000000LL
#define mx10 10000000000LL
#define mx5 100000
#define mx8 100000000LL
#define mx7 10000000LL
#define mx6 1000000LL
#define mx6_5 5000000
#define last 4444444444
 #define f first
 #define s second
 #define rep(i,a,b) for(ll i=(a);i<=(b);i++)
#define reprev(i,a,b) for(ll i=(a);i>=(b);i--)
 #define repi(i,a,b) for(int i=(a);i<=(b);i++)
#define reprevi(i,a,b) for(int i=(a);i>=(b);i--)
#define mp make_pair
#define pb push_back
#define x first
#define y second
//#define PI 3.14159265
const long double PI = 2*acos(0.0);

typedef vector<bool> vb;
void print(vi &a)
{

    for(int i:a)
    {
        cout<<i<<" ";
    }
    cout<<"\n";
}
void print(vll &a)
{

    for(ll i:a)
    {
        cout<<i<<" ";
    }
    cout<<"\n";
}
void print(vector<long double> &a)
{

    for(long double i:a)
    {
        cout<<i<<" ";
    }
    cout<<"\n";
}
void print(vector<pll> &a)
{

    for(pll i:a)
    {
        cout<<i.f<<" "<<i.s<<"\n";
    }
    cout<<"\n";
}
ll dist_sq(pll a,pll b)
{
    return ((a.x-b.x)*(a.x-b.x)+ (a.y-b.y)*(a.y-b.y));
}

ll po(ll a,ll b)
{
    if(b<=0)
        return 1;
    else if(b==1)
        return a;

    ll vl = po((a*a),b/2);
    if(b%2==0)
        return vl;
    else
        return (vl)*a;
}

int main(void)
{
    ios_base::sync_with_stdio(false);
    int n;
    cin>>n;
    vector<pll> v(n);
    //sort(v.begin(),v.end());
    //ll mx = (*(v.rbegin())).f+1;
    ll mx = 0;
    ll mx2 = 0;
    rep(i,0,n-1)
    {
        cin>>v[i].f>>v[i].s;
        mx = max(v[i].f + (ll)ceil(log2(v[i].s)/2.0),mx);
        mx2 = max(mx2,v[i].f);
    }
    cout<<max(mx,mx2+1);
    //sort(v.begin(),v.end());

    return 0;
}


#include <bits/stdc++.h>

#define pii pair<ld, ld>

#define pb push_back

#define mp make_pair

#define f first
#define s second

#define y1 lsafjaljgfs
#define x1 ajhg

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;

const int N = 1e6 + 1;
const int TMXN = 2e6 + 10;
const int INF = 1e9 + 7;
const ll INFL = 1e18;
const ld EPS = 0.000000000001;

int n;
ll k[N], a[N];

bool f (ll x) {
    for (int i = 1; i <= n; i++) {
        ll cur = 0;
        int cnt = k[i];
        while (cur < a[i] && x > cnt) {
            cnt++;
            if (!cur) {
                cur = 1;
            }
            cur *= 4;
        }
        if (cur >= a[i]) {
            continue;
        } else {
            return false;
        }
    }
    return true;
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%I64d%I64d", &k[i], &a[i]);
    }
    ll l = 0;
    ll r = INF * 2;
    while (r - l > 1) {
        int mid = (l + r) / 2;
        if (f(mid)) {
            r = mid;
        } else {
            l = mid;
        }
    }
    cout << r;
    return 0;
}


#include <bits/stdc++.h>

#define pii pair<ld, ld>

#define pb push_back

#define mp make_pair

#define f first
#define s second

#define y1 lsafjaljgfs
#define x1 ajhg

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;

const int N = 1e6 + 1;
const int TMXN = 2e6 + 10;
const int INF = 1e9 + 7;
const ll INFL = 1e18;
const ld EPS = 0.000000000001;

int n;
ll k[N], a[N];

bool f (ll x) {
    for (int i = 1; i <= n; i++) {
        ll cur = 1;
        int cnt = k[i];
        while (cur < a[i] && x > cnt) {
            cnt++;
            cur *= 4LL;
        }
        if (cur == 1) {
            cur = 0;
        }
        if (cur >= a[i]) {
            continue;
        } else {
            return false;
        }
    }
    return true;
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%I64d%I64d", &k[i], &a[i]);
    }
    ll l = 0;
    ll r = INF * 2;
    while (r - l > 1) {
        int mid = (l + r) / 2;
        if (f(mid)) {
            r = mid;
        } else {
            l = mid;
        }
    }
    cout << r;
    return 0;
}


#include <bits/stdc++.h>

#define pii pair<ld, ld>

#define pb push_back

#define mp make_pair

#define f first
#define s second

#define y1 lsafjaljgfs
#define x1 ajhg

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;

const int N = 1e6 + 1;
const int TMXN = 2e6 + 10;
const int INF = 1e9 + 7;
const ll INFL = 1e18;
const ld EPS = 0.000000000001;

int n;
ll k[N], a[N];

bool f (ll x) {
    for (int i = 1; i <= n; i++) {
        ll cur = 1;
        int cnt = k[i];
        while (cur < a[i] && x > cnt) {
            cnt++;
            cur *= 4LL;
        }
        if (cur >= a[i]) {
            continue;
        } else {
            return false;
        }
    }
    return true;
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%I64d%I64d", &k[i], &a[i]);
    }
    ll l = 0;
    ll r = INF * 2;
    while (r - l > 1) {
        int mid = (l + r) / 2;
        if (f(mid)) {
            r = mid;
        } else {
            l = mid;
        }
    }
    cout << r;
    return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ii pair< ll , ll >
#define se second
#define fi first

using namespace std;
const int N=1e5+5;
ii a[N];

ll pow(ll x , ll n)
{
    ll ans=1;
    for(int i=0;i<n;i++)
    {
        ans*=x;
    }
    return ans;
}

int main()
{
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>a[i].fi>>a[i].se;
    }
    sort(a,a+n);
    for(int i=1;i<n;i++)
    {
        if(a[i].fi-a[i-1].fi<=30)
        {
            a[i].se=max((long long)(a[i-1].se/pow(4,a[i].fi-a[i-1].fi)),a[i].se);
        }
    }
    int i=n-1;
    ll answer=a[i].fi;
    while(a[i].se>0)
    {
        answer++;
        a[i].se=a[i].se/4+(a[i].se%4==0?0:1);
        if(a[i].se==1)
            break;
    }
    cout<<answer<<endl;
    return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ii pair< ll , ll >
#define se second
#define fi first

using namespace std;
const int N=1e5+5;
ii a[N];

ll pows (ll x , ll n)
{
    ll ans=1;
    for(int i=0;i<n;i++)
    {
        ans*=x;
    }
    return ans;
}

int main()
{
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>a[i].fi>>a[i].se;
    }
    sort(a,a+n);
    long long s=0;
    for(int i=1;i<n;i++)
    {
        if(a[i].fi-a[i-1].fi<=30)
        {
            s=(a[i-1].se/pows(4,a[i].fi-a[i-1].fi));
            s+=(a[i-1].se%(pows(4,a[i].fi-a[i-1].fi))==0?0:1);
            a[i].se=max(s,a[i].se);
        }
    }
    int i=n-1;
    ll answer=a[i].fi;
    while(a[i].se>0)
    {
        answer++;
        a[i].se=a[i].se/4+(a[i].se%4==0?0:1);
        if(a[i].se==1)
            break;
    }
    cout<<answer<<endl;
    return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <set>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#include <iostream>
#include <complex>
#define MP make_pair
#define PUF push_front
#define POF pop_front
#define PUB push_back
#define POB pop_back
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;

	LL n;
	map<LL, PLL> mp;

int main() {
	LL k, a, tot, nd, sub, mx = 0;
	map<LL, PLL>::iterator it, nxt, tmp;
	scanf("%d", &n);
	for (int i = 0; i < n; ++i) {
		scanf("%I64d %I64d", &k, &a);
		mp[k] = MP(0, a);
		mx = max(mx, k);
	}
	for (it = mp.begin(); it != mp.end(); ++it) {
		tot = it->second.first + it->second.second;
		if (tot >= 4) {
			nd = tot / 4;
			if (mp.count(it->first + 1) == 0) {
				mp[it->first + 1] = MP(0, 0);
				nxt = mp.find(it->first + 1);
			}
			else {
				nxt = it;
				++nxt;
			}
			sub = nd * 4;
			if (nxt->second.second >= nd) {
				nxt->second.first = nd;
				nxt->second.second -= nd;
				if (tot - nd * 4 > 0 && nxt->second.second > 0) {
					sub = it->second.first + it->second.second;
					--nxt->second.second;
					++nxt->second.first;
				}
			}
			else {
				nxt->second.first += nd;
				nxt->second.second = 0;
			}
			if (it->second.first >= sub)
				it->second.first -= sub;
			else {
				sub -= it->second.first;
				it->second.first = 0;
				it->second.second -= sub;
			}
		}
		else {
			nxt = it;
			++nxt;
			if (nxt != mp.end() && nxt->first == it->first + 1) {
				++nxt->second.first;
				--nxt->second.second;
				it->second = MP(0, 0);
			}
		}
		if (it->second.first + it->second.second == 0) {
			mp.erase(it);
		}
	}
	it = mp.end();
	--it;
	tot = it->second.first + it->second.second;
	if (tot > 1)
		printf("%I64d", it->first + 1);
	else {
		if ((mp.size() == 1 || it->second.second > 0) && it->first != mx)
			printf("%I64d", it->first);
		else
			printf("%I64d", it->first + 1);
	}
	return 0;
}
/*
1
0 1
*/


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <set>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#include <iostream>
#include <complex>
#define MP make_pair
#define PUF push_front
#define POF pop_front
#define PUB push_back
#define POB pop_back
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;

	LL n;
	map<LL, PLL> mp, mp1;

int main() {
	LL k, a, tot, nd, sub, mx = 0;
	map<LL, PLL>::iterator it, nxt, tmp;
	scanf("%d", &n);
	for (int i = 0; i < n; ++i) {
		scanf("%I64d %I64d", &k, &a);
		mp[k] = MP(0, a);
		mx = max(mx, k);
	}
	for (it = mp.begin(); it != mp.end(); ++it) {
		tot = it->second.first + it->second.second;
		if (tot >= 4) {
			nd = tot / 4;
			if (mp.count(it->first + 1) == 0) {
				mp[it->first + 1] = MP(0, 0);
				nxt = mp.find(it->first + 1);
			}
			else {
				nxt = it;
				++nxt;
			}
			sub = nd * 4;
			if (nxt->second.second >= nd) {
				nxt->second.first = nd;
				nxt->second.second -= nd;
				if (tot - nd * 4 > 0 && nxt->second.second > 0) {
					sub = it->second.first + it->second.second;
					--nxt->second.second;
					++nxt->second.first;
				}
			}
			else {
				nxt->second.first += nd;
				nxt->second.second = 0;
			}
			if (it->second.first >= sub)
				it->second.first -= sub;
			else {
				sub -= it->second.first;
				it->second.first = 0;
				it->second.second -= sub;
			}
		}
		else {
			nxt = it;
			++nxt;
			if (nxt != mp.end() && nxt->first == it->first + 1) {
				++nxt->second.first;
				--nxt->second.second;
				it->second = MP(0, 0);
			}
		}
	}
	for (it = mp.begin(); it != mp.end(); ++it) {
		if (it->second.first + it->second.second > 0)
			mp1[it->first] = it->second;
	}
	it = mp1.end();
	--it;
	tot = it->second.first + it->second.second;
	if (tot > 1)
		printf("%I64d", it->first + 1);
	else {
		if ((mp.size() == 1 || it->second.second > 0) && it->first != mx)
			printf("%I64d", it->first);
		else
			printf("%I64d", it->first + 1);
	}
	return 0;
}
/*
1
0 1
*/


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <set>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#include <iostream>
#include <complex>
#define MP make_pair
#define PUF push_front
#define POF pop_front
#define PUB push_back
#define POB pop_back
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;

	LL n;
	map<LL, PLL> mp, mp1;

int main() {
	LL k, a, tot, nd, sub, mx = 0;
	map<LL, PLL>::iterator it, nxt, tmp;
	scanf("%d", &n);
	for (int i = 0; i < n; ++i) {
		scanf("%I64d %I64d", &k, &a);
		mp[k] = MP(0, a);
		mx = max(mx, k);
	}
	for (it = mp.begin(); it != mp.end(); ++it) {
		tot = it->second.first + it->second.second;
		if (tot >= 4) {
			nd = tot / 4;
			if (mp.count(it->first + 1) == 0) {
				mp[it->first + 1] = MP(0, 0);
				nxt = mp.find(it->first + 1);
			}
			else {
				nxt = it;
				++nxt;
			}
			sub = nd * 4;
			if (nxt->second.second >= nd) {
				nxt->second.first = nd;
				nxt->second.second -= nd;
				if (tot - nd * 4 > 0 && nxt->second.second > 0) {
					sub = it->second.first + it->second.second;
					--nxt->second.second;
					++nxt->second.first;
				}
			}
			else {
				nxt->second.first += nd;
				nxt->second.second = 0;
			}
			if (it->second.first >= sub)
				it->second.first -= sub;
			else {
				sub -= it->second.first;
				it->second.first = 0;
				it->second.second -= sub;
			}
		}
		else {
			nxt = it;
			++nxt;
			if (nxt != mp.end() && nxt->first == it->first + 1) {
				++nxt->second.first;
				--nxt->second.second;
				it->second = MP(0, 0);
			}
		}
	}
	for (it = mp.begin(); it != mp.end(); ++it) {
		if (it->second.first + it->second.second > 0)
			mp1[it->first] = it->second;
	}
	it = mp1.end();
	--it;
	tot = it->second.first + it->second.second;
	if (tot > 1)
		printf("%I64d", it->first + 1);
	else {
		if ((mp1.size() == 1 || it->second.second > 0) && it->first != mx)
			printf("%I64d", it->first);
		else
			printf("%I64d", it->first + 1);
	}
	return 0;
}
/*
1
0 1
*/


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <set>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#include <iostream>
#include <complex>
#define MP make_pair
#define PUF push_front
#define POF pop_front
#define PUB push_back
#define POB pop_back
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;

	LL n;
	map<LL, PLL> mp;

int main() {
	LL k, a, tot, nd, sub;
	map<LL, PLL>::iterator it, nxt, tmp;
	scanf("%d", &n);
	for (int i = 0; i < n; ++i) {
		scanf("%I64d %I64d", &k, &a);
		mp[k] = MP(0, a);
	}
	for (it = mp.begin(); it != mp.end(); ++it) {
		tot = it->second.first + it->second.second;
		if (tot >= 4) {
			nd = tot / 4;
			if (mp.count(it->first + 1) == 0) {
				mp[it->first + 1] = MP(0, 0);
				nxt = mp.find(it->first + 1);
			}
			else {
				nxt = it;
				++nxt;
			}
			sub = nd * 4;
			if (nxt->second.second >= nd) {
				nxt->second.first = nd;
				nxt->second.second -= nd;
				if (tot - nd * 4 > 0 && nxt->second.second > 0) {
					sub = it->second.first + it->second.second;
					--nxt->second.second;
					++nxt->second.first;
				}
			}
			else {
				nxt->second.first += nd;
				nxt->second.second = 0;
			}
			if (it->second.first >= sub)
				it->second.first -= sub;
			else {
				sub -= it->second.first;
				it->second.first = 0;
				it->second.second -= sub;
			}
		}
		else {
			nxt = it;
			++nxt;
			if (nxt->first == it->first + 1) {
				++nxt->second.first;
				--nxt->second.second;
				it->second = MP(0, 0);
			}
		}
		if (it->second.first + it->second.second == 0) {
			mp.erase(it);
		}
	}
	it = mp.end();
	--it;
	tot = it->second.first + it->second.second;
	if (tot > 1)
		printf("%I64d", it->first + 1);
	else {
		if (mp.size() == 1 || it->second.second > 0)
			printf("%I64d", it->first);
		else
			printf("%I64d", it->first + 1);
	}
	return 0;
}
/*
*/


#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <set>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#include <iostream>
#include <complex>
#define MP make_pair
#define PUF push_front
#define POF pop_front
#define PUB push_back
#define POB pop_back
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;

	double EPS = 1e-6;
	LL n;
	map<LL, LL> mp;

int main() {
	LL k, a, prv;
	double sm;
	map<LL, LL>::iterator it;
	scanf("%d", &n);
	for (int i = 0; i < n; ++i) {
		scanf("%I64d %I64d", &k, &a);
		mp[k] = a;
	}
	for (it = mp.begin(); it != mp.end(); ++it) {
		if (it != mp.begin()) {
			for (LL i = prv; i < it->first; ++i) {
				sm /= 4;
				if (sm < EPS) {
					sm = 0;
					break;
				}
			}
			sm = max(sm, (double) it->second);
		}
		else
			sm = it->second;
		prv = it->first;
	}
	do {
		++prv;
		sm /= 4;
	} while (sm > 1);
	printf("%I64d\n", prv);
	return 0;
}
/*
3
1 4
0 17
2 4
*/


#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fastread ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define openfile freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#define f(i, x, y) for(int i = x; i < y; i++)
#define all(X) X.begin(), X.end()
#define int long long
#define key pair<int, int>
#define ff first
#define ss second
int mod = 1e9 + 7;
const int inf = 2e18;
using namespace std;

main()
{
    int n;  cin>>n; key k[n+2];
    f(i, 1, n+1) cin>>k[i].ff>>k[i].ss;
    sort(k+1, k+n+1);
    k[n+1] = {k[n].ff+1, 0};
    int i = 1;
    while(i <= n)
    {
        int j = i, t = 0;
        while(i <= n && k[i].ff == k[j].ff) t += k[i++].ss;
        if(k[i].ff - k[j].ff > 30) continue;
        if(i == n+1 && t == 1)
        {
            k[i].ff = k[i-1].ff; break;
        }
        i--;
        int y = pow(4, k[i+1].ff - k[i].ff);
        int x = (t/y) + ((t % y == 0) ? 0 : 1);
        k[i+1].ss += max((int)0, x - k[i+1].ss);
        i++;
    }
    while(k[n+1].ss > 1)
    {
        int t = (k[n+1].ss / 4) + ((k[n+1].ss % 4 != 0)? 1 : 0);
        k[n+1].ss = t; k[n+1].ff++;
    }
    cout<<k[n+1].ff;

}


#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fastread ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define openfile freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#define f(i, x, y) for(int i = x; i < y; i++)
#define all(X) X.begin(), X.end()
#define int long long
#define key pair<int, int>
#define ff first
#define ss second
int mod = 1e9 + 7;
const int inf = 2e18;
using namespace std;

main()
{
    int n;  cin>>n; key k[n+2];
    f(i, 1, n+1) cin>>k[i].ff>>k[i].ss;
    sort(k+1, k+n+1);
    k[n+1] = {k[n].ff+1, 0};
    int i = 1;
    while(i <= n)
    {
        int j = i, t = 0;
        while(i <= n && k[i].ff == k[j].ff) t += k[i++].ss;
        if(k[i].ff - k[j].ff > 30) continue;
        i--;
        int y = pow(4, k[i+1].ff - k[i].ff);
        int x = (t/y) + ((t % y == 0) ? 0 : 1);
        k[i+1].ss += max((int)0, x - k[i+1].ss);
        i++;
    }
    while(k[n+1].ss > 1)
    {
        int t = (k[n+1].ss / 4) + ((k[n+1].ss % 4 != 0)? 1 : 0);
        k[n+1].ss = t; k[n+1].ff++;
    }
    cout<<k[n+1].ff;

}


#include <bits/stdc++.h>
#define rep(i, x, y) for (int i = x; i <= y; i++)
using namespace std;

const int N = 1e5 + 10;
typedef long long ll;
ll n, ans;
struct node { ll k, a; }e[N];

bool cmp(node x, node y) {
	return x.k < y.k;
}

int main() {
	cin >> n;
	rep(i, 1, n) scanf("%lld%lld", &e[i].k, &e[i].a);
	sort(e + 1, e + n + 1, cmp);
	rep(i, 1, n - 1) {
		ll tmp = e[i + 1].k - e[i].k;
		if (tmp >= 15) continue;
		ll num = 1;
		rep(j, 1, tmp) num *= 4;
		if (num * e[i + 1].a < e[i].a) {
			e[i].a -= num * e[i + 1].a;
			e[i + 1].a += e[i].a / num + (e[i].a % num > 0);
		}
	}
	ans = e[n].k + 1;
	ll num = 4;
	rep(i, 1, 14) {
		if (num >= e[n].a) return printf("%lld\n", ans), 0;
		ans++, num *= 4;
	}

    /* ans = e[n].k;
    double t = (double)e[n].a - 0.1;
    if (e[n].a == 1) { printf("%lld\n", ans + 1); return 0; }
    while (t >= 1) {
    	ans++, t /= 4;
    } printf("%lld\n", ans);*/
	return 0;
}


#include <bits/stdc++.h>
#define rep(i, x, y) for (int i = x; i <= y; i++)
using namespace std;

const int N = 1e5 + 10;
typedef long long ll;
ll n, ans;
struct node { ll k, a; }e[N];

bool cmp(node x, node y) {
	return x.k < y.k;
}

int main() {
	cin >> n;
	rep(i, 1, n) scanf("%lld%lld", &e[i].k, &e[i].a);
	sort(e + 1, e + n + 1, cmp);
	rep(i, 1, n - 1) {
		ll tmp = e[i + 1].k - e[i].k;
		if (tmp >= 15) continue;
		ll num = 1;
		rep(j, 1, tmp) num *= 4;
		if (num * e[i + 1].a < e[i].a) {
			e[i].a -= num * e[i + 1].a;
			e[i + 1].a += e[i].a / num + (e[i].a % num > 0);
		}
	}
	ans = e[n].k + 1;
	ll num = 4;
	rep(i, 1, 16) {
		if (num >= e[n].a) return printf("%lld\n", ans), 0;
		ans++, num *= 4;
	}

    /* ans = e[n].k;
    double t = (double)e[n].a - 0.1;
    if (e[n].a == 1) { printf("%lld\n", ans + 1); return 0; }
    while (t >= 1) {
    	ans++, t /= 4;
    } printf("%lld\n", ans);*/
	return 0;
}