#include <bits/stdc++.h>

#define F first
#define S second
#define pb push_back
#define all(x) x.begin(), x.end()
#define int long long

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

const int N = 200000 + 10;
const int MOD = 1000000007;
const int LOG = 20;
const int INF = 1000000010;
const int delta = 11353;

int n, k, ans[N], TP[N], D[N];
bool Can[N];
vi V[N];
multiset<int> Tak[N];

int32_t main(){
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	//freopen("soal1.in", "r", stdin);
	cin >> n >> k;
	bool f = 0;
	//freopen("soal1.in", "r", stdin);
	for (int i = 1; i <= n; i++){
		int c, v;
		cin >> c >> v;
		V[c].pb(v);
	}	
	for (int i = 1; i <= k; i++) f |= ((int)V[i].size() > 2);
	for (int i = 2; i <= n; i++){
		if (i % 2 == 0) Can[i] = 1;
		else if(f) Can[i] = 1;
	}
	vector<pair<pair<long double, int>, int>> num;
	set<pii> T3, Dou;
	multiset<int> Sol;
	multiset<int> T1;
	for (int i = 1; i <= k; i++){
		sort(all(V[i]));
		reverse(all(V[i]));
		num.pb({{(V[i][0] + V[i][1]) * 1.0 / 2.0, i}, 1});
		D[i] = V[i][0] + V[i][1];
		for (int j = 2; j < V[i].size(); j++) Tak[i].insert(V[i][j]),num.pb({{V[i][j], i}, 0});
		if (V[i].size() >= 3) TP[i] = V[i][0] + V[i][1] + V[i][2], T3.insert({TP[i], i});
	}
	sort(all(num));
	reverse(all(num));
	int sm = 0;
	int cnt = 0;
	for (auto u:num){
		//cout << u.F.F << ' ' << u.F.S << ' ' << u.S << '\n';
		if (u.S == 0){
			sm += u.F.F;
			ans[++cnt] = sm;
			Sol.insert((int)u.F.F);
			Tak[u.F.S].erase(Tak[u.F.S].find((int)u.F.F));
			T1.erase(T1.find((int)u.F.F));
			if (Tak[u.F.S].size())T1.insert(*Tak[u.F.S].rbegin());
			Dou.erase({D[u.F.S], u.F.S});
			continue;
		}
		u.F.F *= 2;
		cnt++;
		if (Can[cnt]){
			//cout << "Fuck " << sm << '\n';
			//if (cnt == 68) cout << "Fuck\n" << '\n';
			if (Sol.size()) ans[cnt] = max(ans[cnt], sm - (*Sol.begin()) + (int)u.F.F);
			//if (cnt == 7) cout << "Fuck " << ans[cnt] << '\n';
			if (Dou.size() && T3.size()){
				ans[cnt] = max(ans[cnt], sm - (*Dou.begin()).F + (*T3.rbegin()).F);
			} 
			//if (cnt == 7) cout << "Fuck " << ans[cnt] << '\n';
			if (T1.size()) ans[cnt] = max(ans[cnt], sm + (*T1.rbegin()));
			//if (cnt == 7) cout <<"Fuck " << ans[cnt] << '\n';
		}
		if (Tak[u.F.S].size() != 0) T1.insert(*Tak[u.F.S].rbegin());
		Dou.insert({(int)u.F.F, u.F.S});
		T3.erase({TP[u.F.S], u.F.S});
		sm += u.F.F;
		cnt++;
		//if (cnt == 6) return cout << "Fuck\n", 0;
		ans[cnt] = sm;
	}
	//cout << "Yes\n";
//	freopen("soal1.out", "r", stdin);
	for (int i = 1; i <= n; i++){
		cout << (Can[i] ? ans[i]:-1) << '\n';
	}

	return 0;
}
