#include <bits/stdc++.h>
#pragma comment(linker, "/stack:128000000")
using namespace std;
template <typename X>
inline X abs(const X& a) {
  return a < 0 ? -a : a;
}
template <typename X>
inline X sqr(const X& a) {
  return a * a;
}
const int INF = INT_MAX / 2;
const long double EPS = 1e-9;
const long double PI = 3.1415926535897932384626433832795;
const int M = 10 * 1000 + 3;
int n, m;
vector<pair<int, string> > z[M];
const int L = 10 + 3;
char buf[L];
inline bool read() {
  if (scanf("%d%d", &n, &m) != 2) return false;
  for (int i = 0; i < int(n); i++) {
    int r, first;
    assert(scanf("%s%d%d", buf, &r, &first) == 3);
    r--;
    string name = string(buf);
    z[r].push_back(make_pair((first), (name)));
  }
  return true;
}
inline void solve() {
  for (int i = 0; i < int(m); i++) {
    assert(int((z[i]).size()) >= 2);
    sort((z[i]).begin(), (z[i]).end());
    reverse((z[i]).begin(), (z[i]).end());
  }
  for (int i = 0; i < int(m); i++) {
    if (int((z[i]).size()) >= 3 && z[i][1].first == z[i][2].first)
      puts("?");
    else
      printf("%s %s\n", z[i][0].second.c_str(), z[i][1].second.c_str());
  }
}
int main() {
  assert(read());
  solve();
  return 0;
}
