#include <bits/stdc++.h>
using namespace std;
template <class T>
ostream &operator<<(ostream &os, vector<T> V) {
  os << "[ ";
  for (auto v : V) os << v << " ";
  os << "]";
  return os;
}
template <class T>
ostream &operator<<(ostream &os, set<T> S) {
  os << "{ ";
  for (auto s : S) os << s << " ";
  return os << "}";
}
template <class L, class R>
ostream &operator<<(ostream &os, pair<L, R> P) {
  return os << "(" << P.first << "," << P.second << ")";
}
template <class L, class R>
ostream &operator<<(ostream &os, map<L, R> M) {
  os << "{ ";
  for (auto m : M) os << "(" << m.first << ":" << m.second << ") ";
  return os << "}";
}
const long long N = 100005;
vector<pair<long long, string>> p[N];
bool compare(pair<long long, string> a, pair<long long, string> b) {
  return a.first > b.first;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  long long n, m;
  cin >> n >> m;
  for (long long i = 1; i < n + 1; i++) {
    string s;
    long long x, sc;
    cin >> s >> x >> sc;
    p[x].push_back({sc, s});
  }
  for (long long i = 1; i < m + 1; i++) sort(p[i].begin(), p[i].end(), compare);
  for (long long i = 1; i < m + 1; i++) {
    if (p[i].size() == 2) {
      cout << p[i][0].second << ' ' << p[i][1].second << '\n';
    } else {
      if (p[i][1].first == p[i][2].first)
        cout << "?\n";
      else
        cout << p[i][0].second << ' ' << p[i][1].second << '\n';
    }
  }
  return 0;
}
