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

#define rep(i,n) for(ll i = 0; i < (ll)n; i++)
#define swap(a,b) a^=b;b^=a;a^=b;
//#define for(i,a,b) for (ll i=(a);i<(ll)b; i++)
#define print(x) std::cout << x << std::endl;

using namespace std;

typedef long long ll;

template<class T, class U> std::string replace(std::string s, const T& target, const U& replacement, bool replace_first = 0, bool replace_empty = 0);
bool isContain(int value, int under, int top);
vector<int> range(int x);

int get_ab(string str) {
	bool isA = false;
	int res = 0;
	if (str[0] == 'A') isA = true;
	for (int i = 1; i < str.length(); i++) {
		if (isA && str[i] == 'B') { res++; isA = false; }
		else if (str[i] == 'A') isA = true;
		else isA = false;
	}
	return res;
}

vector<bool> isVisited;
vector<int> Accu;
vector<vector<int>> Datas;
int N;

void DEF(int pos,int sum) {
	bool all_visited = true;
	rep(i,N) 
		if (isVisited[i] == false) {
			all_visited = false;
			break;
		}

	Accu[pos] = sum;

	rep(i, N) {
		if (isVisited[i] == true) continue; //すでに訪れている
		if (Datas[pos][i] == -1)  continue; //繋がっていない
		isVisited[i] = true;
		DEF(i, sum + Datas[pos][i]);
	}
}

ll gcd(ll A, ll B) {
	int r = A % B;
	while (r != 0) {
		A = B;
		B = r;
		r = A % B;
	}

	return B;
}

vector<bool> to_binary(int x) {
	vector<bool> res;
	while (x != 0) {
		res.push_back(x % 2);
		x /= 2;
	}
	return res;
}

vector<bool> pad(vector<bool> inp,int num) {
	while (inp.size() != num) {
		inp.push_back(false);
	}
	return inp;
}

int main(void) {
	//Program Start	

	int N;
	cin >> N;

	multiset<tuple<string, int,int>> data;

	string S;
	int P;

	rep(i, N) {
		cin >> S >> P;
		data.insert(tuple<string,int,int>(S, 100 - P, i));
	}

	for (auto iter = data.begin(); iter != data.end(); iter++) {
		//cout << std::get<0>(*iter) + " " + to_string(std::get<1>(*iter)) + " " + to_string(std::get<2>(*iter)) << endl;
		cout << to_string(std::get<2>(*iter) + 1) << endl;
	}


	/*
	int N, M;
	cin >> N >> M;

	vector<int> K(M);
	vector<vector<int>> s(M);
	vector<int> p(M);

	rep(i, M) {
		cin >> K[i];
		s[i].resize(K[i]);
		rep(j, K[i]) {
			cin >> s[i][j];
		}
	}

	rep(i, M) {
		cin >> p[i];
	}


	int loopnum = (int)pow(2, N - 1);
	int ans = 0;

	vector<bool> tmp;
	rep(i, loopnum) {
		tmp = to_binary(i);
		tmp = pad(tmp, loopnum);
		reverse(tmp.begin(), tmp.end());
		bool isadd = true;
		rep(j, M) {
			for (auto e : tmp)
				cout << e << endl;
			cout << endl;
			int isok = 0;
			rep(l, K[j]) {
				//cout << tmp.size() << endl;
				//isok ^= tmp[s[j][l] - 1];
				isok += tmp[s[j][l] - 1];
			}
			//if (isok != (p[j] == 1)) {
			if((isok % 2) != p[j]) {
				isadd = false;
				break;
			}
		}
		if (isadd == true) ans++;
	}


	cout << ans << endl;

	*/



ProgramEndPointLabel:;


	//Program End
	system("pause");

	return 0;
}


vector<int> range(int y) {
	vector<int> result(y);
	for (int i = 0; i < y; i++)
		result[i] = i;
	return result;
}

bool isContain(int value, int under, int top) {
	if (under <= value && value <= top) return true;
	return false;
}

template<class T, class U> std::string replace(std::string s, const T& target, const U& replacement, bool replace_first, bool replace_empty) {
	using S = std::string;
	using C = std::string::value_type;
	using N = std::string::size_type;
	struct {
		auto len(const S& s) { return s.size(); }
		auto len(const C* p) { return std::char_traits<C>::length(p); }
		auto len(const C  c) { return 1; }
		auto sub(S* s, const S& t, N pos, N len) { s->replace(pos, len, t); }
		auto sub(S* s, const C* t, N pos, N len) { s->replace(pos, len, t); }
		auto sub(S* s, const C  t, N pos, N len) { s->replace(pos, len, 1, t); }
		auto ins(S* s, const S& t, N pos) { s->insert(pos, t); }
		auto ins(S* s, const C* t, N pos) { s->insert(pos, t); }
		auto ins(S* s, const C  t, N pos) { s->insert(pos, 1, t); }
	} util;

	N target_length = util.len(target);
	N replacement_length = util.len(replacement);
	if (target_length == 0) {
		if (!replace_empty || replacement_length == 0) return s;
		N n = s.size() + replacement_length * (1 + s.size());
		s.reserve(!replace_first ? n : s.size() + replacement_length);
		for (N i = 0; i < n; i += 1 + replacement_length) {
			util.ins(&s, replacement, i);
			if (replace_first) break;
		}
		return s;
	}

	N pos = 0;
	while ((pos = s.find(target, pos)) != std::string::npos) {
		util.sub(&s, replacement, pos, target_length);
		if (replace_first) return s;
		pos += replacement_length;
	}
	return s;
}


Measured memory_bytes: 504