#include <bits/stdc++.h>
using namespace std;
void merge(vector<pair<int, string>> &a, vector<pair<int, string>> &b,
           vector<pair<int, string>> &c) {
  long long int counter1 = 0, counter2 = 0;
  a.clear();
  while (counter1 < b.size() && counter2 < c.size()) {
    if (b[counter1].first > c[counter2].first) {
      a.push_back(b[counter1++]);
    } else {
      a.push_back(c[counter2++]);
    }
  }
  while (counter1 < b.size()) {
    a.push_back(b[counter1++]);
  }
  while (counter2 < c.size()) {
    a.push_back(c[counter2++]);
  }
  return;
}
void merge_sort(vector<pair<int, string>> &a) {
  long long int i;
  if (a.size() <= 1)
    return;
  else {
    vector<pair<int, string>> b;
    vector<pair<int, string>> c;
    long long int mid = a.size() / 2 - 1;
    for (i = 0; i <= mid; i++) b.push_back(a[i]);
    for (i = mid + 1; i <= a.size() - 1; i++) c.push_back(a[i]);
    merge_sort(b);
    merge_sort(c);
    merge(a, b, c);
    return;
  }
}
int main() {
  long long n, m, i, j, count1, count2, k;
  cin >> n >> m;
  getchar();
  vector<pair<int, string>> vec[m + 1];
  string name[n], sur[n], region[n], mar[n];
  long long int marks[n], r[n];
  for (i = 0; i < n; i++) {
    getline(cin, name[i]);
    j = 0;
    sur[i] = "";
    region[i] = "";
    mar[i] = "";
    while (name[i][j] != ' ') {
      sur[i] += name[i][j];
      j++;
    }
    j++;
    while (name[i][j] != ' ') {
      region[i] += name[i][j];
      j++;
    }
    r[i] = stoi(region[i]);
    j++;
    while (j < name[i].length()) {
      mar[i] += name[i][j];
      j++;
    }
    marks[i] = stoi(mar[i]);
    vec[r[i]].push_back(make_pair(marks[i], sur[i]));
  }
  for (i = 1; i <= m; i++) {
    merge_sort(vec[i]);
  }
  for (i = 1; i <= m; i++) {
    if (vec[i].size() == 2) {
      cout << vec[i][0].second << " " << vec[i][1].second << "\n";
    } else {
      count1 = 0;
      count2 = 0;
      j = 0;
      while (j < vec[i].size()) {
        if (vec[i][j].first == vec[i][0].first)
          count1++;
        else
          break;
        j++;
      }
      k = j;
      while (k < vec[i].size()) {
        if (vec[i][k].first == vec[i][j].first)
          count2++;
        else
          break;
        k++;
      }
      if (count1 >= 3 || (count1 == 1 && count2 >= 2)) {
        cout << "?\n";
      } else {
        cout << vec[i][0].second << " " << vec[i][1].second << "\n";
      }
    }
  }
  return 0;
}
