package main
import (
"bufio"
"fmt"
"os"
"sort"
)
type Dancer struct {
id int
p int
}
type Point struct {
x, y int
}
func main() {
in := bufio.NewReader(os.Stdin)
out := bufio.NewWriter(os.Stdout)
defer out.Flush()
var n, w, h int
fmt.Fscan(in, &n, &w, &h)
const offset = 100005
const maxSize = 200010
G1 := make([][]Dancer, maxSize)
G2 := make([][]Dancer, maxSize)
for i := 0; i < n; i++ {
var g, p, t int
fmt.Fscan(in, &g, &p, &t)
c := p - t + offset
if g == 1 {
G1[c] = append(G1[c], Dancer{id: i, p: p})
} else {
G2[c] = append(G2[c], Dancer{id: i, p: p})
}
}
ans := make([]Point, n)
for c := 0; c < maxSize; c++ {
if len(G1[c]) == 0 && len(G2[c]) == 0 {
continue
}
g1 := G1[c]
g2 := G2[c]
if len(g1) > 1 {
sort.Slice(g1, func(i, j int) bool {
return g1[i].p < g1[j].p
})
}
if len(g2) > 1 {
sort.Slice(g2, func(i, j int) bool {
return g2[i].p > g2[j].p
})
}
dancers := make([]Dancer, 0, len(g1)+len(g2))
dancers = append(dancers, g2...)
dancers = append(dancers, g1...)
dests := make([]Point, 0, len(g1)+len(g2))
for _, d := range g1 {
dests = append(dests, Point{d.p, h})
}
for _, d := range g2 {
dests = append(dests, Point{w, d.p})
}
for i, d := range dancers {
ans[d.id] = dests[i]
}
}
for _, p := range ans {
fmt.Fprintf(out, "%d %d\n", p.x, p.y)
}
}