#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
ll GD(ll num){//各桁の和
    ll digit=0;
    while(num!=0){
        num /= 10;
        digit++;
    }
    return digit;
}
bool is_integer( long double x ){//整数判定
  return std::floor(x)==x;
}

int gcd(int aaa, int bbb)//最大公約数
{
   if (aaa%bbb == 0)
   {
       return(bbb);
   }
   else
   {
       return(gcd(bbb, aaa%bbb));
   }
}

int lcm(int aaa, int bbb)//最小公倍数
{
   return aaa * bbb / gcd(aaa, bbb);
}

int main() {
  int N;
  cin>>N;
  map<int,tuple<int,int,int,int,int,int,int,int,ll>> score;
  set<int> Y;
  //棒大量生成するんご！！！！！！！
  for(int i=0;i<N;i++){
   int a,b;
    ll c;
    cin>>a>>b>>c;
    score[i]=make_tuple(a,b,a+1,b,a,b+1,a+1,b+1,c);
    Y.insert(b);
  }
  Y.insert(10000);
  for(int j=0;j<N;j++){
    set<int> S;
    set<int> min_sum;
    for(int k=0;k<N;k++){
     if(k!=j){
       	if( get<1>(score[j])==get<1>(score[k])&&get<2>(score[j])<=get<0>(score[k])){
          S.insert(get<0>(score[k]));
        }
       if( get<1>(score[j])==get<1>(score[k])&&get<0>(score[j])>=get<2>(score[k])){
         min_sum.insert(get<0>(score[k]));
       }
     }
    }
    if(S.empty()){
      int s1,s2,s3,s4,s5,s6,s7,s8;
      ll s9;
      tie(s1,s2,s3,s4,s5,s6,s7,s8,s9) = score[j];
      s3=10000;
      s7=10000;
      if(min_sum.empty()){
       s1=0;
        s5=0;
      }
      score[j]=make_tuple(s1,s2,s3,s4,s5,s6,s7,s8,s9);
    }else{
      int s1,s2,s3,s4,s5,s6,s7,s8;
      ll s9;
      tie(s1,s2,s3,s4,s5,s6,s7,s8,s9) = score[j];
      s3=*begin(S);
      s7=*begin(S);
            if(min_sum.empty()){
       s1=0;
        s5=0;
      }
      score[j]=make_tuple(s1,s2,s3,s4,s5,s6,s7,s8,s9);
    }
  }
  //ひろげていくんご！！！！
  int y=Y.size();
  map<int,int> coordinate1;
  map<int,int> coordinate2;
  int n=0;
   for (auto value : Y) {
  coordinate1[value]=n;
  coordinate2[n]=value;
     n++;
}
  for(int o=0;o<N;o++){
      int t1,t2,t3,t4,t5,t6,t7,t8;
      ll t9;
      tie(t1,t2,t3,t4,t5,t6,t7,t8,t9) = score[o];
    int hoga=coordinate1[t4];
    int hogi=coordinate2[hoga+1];
    ll hogu=t9/(t3-t1);
    if(hogi-t8<=hogu){
      t6+=hogi-t8;
      t8+=hogi-t8;
    }else{
      t6+=hogu;
      t8+=hogu;
    }
    if(*begin(Y)==t2){
    t2=0;
     t4=0;
   }
    score[o]=make_tuple(t1,t2,t3,t4,t5,t6,t7,t8,t9);
  }
  
  for(int l=0;l<N;l++){
    int x1,x2,x3,x4,x5,x6,x7,x8;
    ll x9;
    tie(x1,x2,x3,x4,x5,x6,x7,x8,x9) = score[l];
    cout<<x1<<" "<<x2<<" "<<x7<<" "<<x8<<endl;
  }
}

#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define _GLIBCXX_DEBUG
typedef long long int ll;
typedef long double ld;

const int inf = 10000;

struct Point {
  int x;
  int y;
};

struct Rect {
  Point start;
  Point end;
};

int main() {
  int n;
  cin >> n;
  vector<Point> ad(n);

  // input
  rep(i, n) {
    int _;  // 一旦面積は考えない
    cin >> ad[i].x >> ad[i].y;
    cin >> _;
  }

  // 最初に x 座標を決める
  // 次でy座標を決めるといい感じになる

  vector<Rect> ans(n);
  // calc
  rep(i, n) {
    ans[i].start.x = ad[i].x;
    ans[i].start.y = ad[i].y;
  }

  rep(i, n) {
    int c = inf;

    rep(j, n) {
      if (i == j) continue;

      if (ad[i].x <= ad[j].x) {
        c = min(c, ad[j].x);
      }
    }
    ans[i].end.x = (c == ad[i].x) ? ad[i].x + 1 : c;
  }

  rep(i, n) {
    int d = inf;
    bool isSameX = false;
    rep(j, n) {
      if (i == j) continue;
      if (ad[i].x == ad[j].x) {
        isSameX = true;
        break;
      }
    }
    if (!isSameX) {
      ans[i].start.y = 0;
    }

    rep(j, n) {
      if (i == j) continue;

      if ((ad[i].x <= ad[j].x && ad[j].x <= ans[i].end.x) &&
          (ad[i].y <= ad[j].y)) {
        d = min(d, ad[j].y);
      }
    }
    ans[i].end.y = (d == ad[i].y) ? ad[i].y + 1 : d;
  }

  // output
  rep(i, n) {
    int a = ans[i].start.x;
    int b = ans[i].start.y;
    int c = ans[i].end.x;
    int d = ans[i].end.y;
    printf("%d %d %d %d\n", a, b, c, d);
  }
}
