#include <bits/stdc++.h>
using namespace std;
struct ASDF {
  ASDF& operator,(int& a) {
    scanf("%d", &a);
    return *this;
  }
  ASDF& operator,(long int& a) {
    scanf("%ld", &a);
    return *this;
  }
  ASDF& operator,(long long int& a) {
    scanf("%lld", &a);
    return *this;
  }
  ASDF& operator,(char& c) {
    scanf("%c", &c);
    return *this;
  }
  ASDF& operator,(double& d) {
    scanf("%lf", &d);
    return *this;
  }
  template <typename T>
  ASDF& operator,(T& a) {
    cin >> a;
    return *this;
  }
} asdf;
template <typename T>
ostream& operator<<(ostream& output, vector<T>& v) {
  output << "[ ";
  if (int(v.size())) {
    output << v[0];
  }
  for (int i = 1; i < int(v.size()); i++) {
    output << ", " << v[i];
  }
  output << " ]";
  return output;
}
template <typename T1, typename T2>
ostream& operator<<(ostream& output, pair<T1, T2>& p) {
  output << "( " << p.first << ", " << p.second << " )";
  return output;
}
int main() {
  int n;
  set<pair<long long, int> > w, b;
  int c;
  long long s;
  cin >> n;
  for (int i = 0; i < n; i++) {
    cin >> c >> s;
    if (c == 0) {
      w.insert(make_pair(s, i));
    } else {
      b.insert(make_pair(s, i));
    }
  }
  vector<pair<pair<int, int>, long long> > res;
  while (!w.empty() && !b.empty()) {
    pair<long long, int> wh = *w.begin(), bl = *b.begin();
    w.erase(wh);
    b.erase(bl);
    long long mn = min(wh.first, bl.first);
    wh.first -= mn;
    bl.first -= mn;
    res.push_back(make_pair(make_pair(wh.second, bl.second), mn));
    if (wh.first || (!wh.first && !bl.first && int(w.size()) < int(b.size()))) {
      w.insert(wh);
    } else {
      b.insert(bl);
    }
  }
  for (vector<pair<pair<int, int>, long long> >::iterator it = res.begin();
       it != res.end(); it++) {
    cout << it->first.first + 1 << " " << it->first.second + 1 << " "
         << it->second << endl;
  }
  return 0;
}
