use std::cmp::Ordering;
use std::fmt::Debug;
#[allow(unused_imports)]
use std::fs::File;
#[allow(unused_imports)]
use std::io::{stdin, stdout, BufReader, BufWriter, Read, Write};
use std::str::FromStr;

pub fn start<R: Read, W: Write>(input: R, output: &mut W) {
    let mut scanner = Scanner::new(input.bytes().map(Result::unwrap));
    let n = scanner.next_value::<isize>();
    let l = scanner.next_value::<isize>(); // 長さ l <= 10^9
    let t = scanner.next_value::<isize>(); // 時間 t <= 10^9
    let xw = scanner.next_2darray::<isize>(2, n as usize); // x = position,  w == 1 増, w == 2 減

    let mut seq = (0..n as usize).into_iter().collect::<Vec<_>>();
    seq.sort_by_key(|&x| xw[x][0] << 1 | xw[x][1] & 1);

    let mut results = Vec::new(); // 現在位置のリストを作成
    let mut shift = 0; // ゼロ点を通過した蟻の数
    for x in xw {
        if x[1] == 1 {
            let mut r = x[0] + t;
            while r >= l {
                r -= l;
                shift += 1;
            }
            results.push(r);
        } else {
            let mut r = x[0] - t;
            while r < 0 {
                r += l;
                shift -= 1;
            }
            results.push(r);
        }
    }
    results.sort();
    while shift < 0 {
        shift += n;
    }
    while shift >= n {
        shift -= n;
    }
    for i in shift..n {
        write!(output, "{}\n", results[seq[i as usize]]).unwrap();
    }
    for i in 0..(shift as usize) {
        write!(output, "{}\n", results[seq[i]]).unwrap();
    }
}

////////////////////////////
// Tests
////////////////////////////

#[cfg(test)]
mod test {
    use super::start;
    use std::ffi::OsStr;
    use std::fs;
    use std::fs::File;
    use std::io::Cursor;
    use std::io::{BufReader, Read};

    #[test]
    fn example() {
        let mut entries = fs::read_dir("./tests")
            .unwrap()
            .into_iter()
            .flat_map(|x| x.ok())
            .map(|x| x.path())
            .filter(|x| x.extension().unwrap_or(OsStr::new("")).to_string_lossy() == "in")
            .collect::<Vec<_>>();
        entries.sort();
        for entry in entries {
            let mut output = Vec::new();
            BufReader::new(File::open(entry.with_extension("out")).unwrap())
                .read_to_end(&mut output)
                .unwrap();
            let input = BufReader::new(File::open(entry).unwrap());

            let mut out = Cursor::new(Vec::new());
            start(input, &mut out);
            let outvec = out.into_inner();
            println!("{}", String::from_utf8((&outvec).to_vec()).unwrap());
            assert_eq!(outvec, output);
        }
    }
}

////////////////////////////
// Snipetts
////////////////////////////

#[allow(dead_code)]
fn main() {
    let stdin = stdin();
    let stdout = stdout();
    let mut out = BufWriter::new(stdout.lock());
    let input = BufReader::new(stdin.lock());
    start(input, &mut out);
}

// // ファイルの場合
// #[allow(dead_code)]
// fn main() {
//     let mut out = BufWriter::new(File::create("output.txt").unwrap());
//     let input = BufReader::new(File::open("input.txt").unwrap());
//     start(input, &mut out);
// }

// 大きなスタックが必要な場合はこちらを利用する
// #[allow(dead_code)]
// fn main() {
//     std::thread::Builder::new()
//         .name("big stack size".into())
//         .stack_size(32 * 1024 * 1024) // 32 MBのスタックサイズ
//         .spawn(|| {
//             let stdin = stdin();
//             let stdout = stdout();
//             let out = BufWriter::new(stdout.lock());
//             let input = BufReader::new(stdin.lock());
//             start(input, out);
//         })
//         .unwrap()
//         .join()
//         .unwrap();
// }

pub struct Scanner<I: Iterator<Item = u8>> {
    input: I,
}

impl<I: Iterator<Item = u8>> Scanner<I> {
    pub fn new(input: I) -> Self {
        Scanner::<I> { input: input }
    }

    // 文字コードはISO/IEC 8859-1 (Latin-1)とする
    pub fn next_value<T: FromStr>(&mut self) -> T
    where
        <T as FromStr>::Err: Debug,
    {
        T::from_str(
            &(self
                .input
                .by_ref()
                .map(char::from)
                .skip_while(|x| x.is_whitespace())
                .take_while(|x| !x.is_whitespace())
                .collect::<String>()),
        )
        .unwrap()
    }

    // 文字コードはISO/IEC 8859-1 (Latin-1)とする
    #[allow(dead_code)]
    pub fn next_bytes(&mut self) -> Vec<u8> {
        self.input
            .by_ref()
            .skip_while(|&x| char::from(x).is_whitespace())
            .take_while(|&x| !char::from(x).is_whitespace())
            .collect::<Vec<_>>()
    }

    #[allow(dead_code)]
    pub fn next_array<T: FromStr>(&mut self, len: usize) -> Vec<T>
    where
        <T as FromStr>::Err: Debug,
    {
        (0..len).map(|_| self.next_value()).collect()
    }

    #[allow(dead_code)]
    pub fn next_2darray<T: FromStr>(&mut self, x: usize, y: usize) -> Vec<Vec<T>>
    where
        <T as FromStr>::Err: Debug,
    {
        (0..y).map(|_| self.next_array(x)).collect()
    }

    #[allow(dead_code)]
    pub fn next_2d_bytes(&mut self, len: usize) -> Vec<Vec<u8>> {
        (0..len).map(|_| self.next_bytes()).collect()
    }
}

// 1.15.1でReverseを使う
// https://qiita.com/hatoo@github/items/fa14ad36a1b568d14f3e
#[derive(Eq, PartialEq, Clone, Debug)]
pub struct Reverse<T>(pub T);

impl<T: PartialOrd> PartialOrd for Reverse<T> {
    fn partial_cmp(&self, other: &Reverse<T>) -> Option<Ordering> {
        other.0.partial_cmp(&self.0)
    }
}

impl<T: Ord> Ord for Reverse<T> {
    fn cmp(&self, other: &Reverse<T>) -> Ordering {
        other.0.cmp(&self.0)
    }
}

// PartialOrdをTotalOrdにするラッパ
// https://qiita.com/hatoo@github/items/fa14ad36a1b568d14f3e

#[derive(PartialEq, PartialOrd)]
pub struct Total<T>(pub T);

impl<T: PartialEq> Eq for Total<T> {}

impl<T: PartialOrd> Ord for Total<T> {
    fn cmp(&self, other: &Total<T>) -> Ordering {
        self.0.partial_cmp(&other.0).unwrap()
    }
}

// 順列生成
#[allow(dead_code)]
pub fn permutations(n: usize, k: usize) -> Box<Iterator<Item = Vec<u8>>> {
    fn inner(array: Vec<u8>, depth: usize, max: u8) -> Box<Iterator<Item = Vec<u8>>> {
        let na = (0..max).flat_map(move |x| {
            if array.contains(&x) {
                None
            } else {
                let mut newarray = array.clone();
                newarray.push(x);
                Some(newarray)
            }
        });
        if depth > 0 {
            Box::new(na.flat_map(move |x| inner(x, depth - 1, max)))
        } else {
            Box::new(na)
        }
    }
    inner(Vec::new(), k - 1, n as u8)
}

// 組み合わせ生成
#[allow(dead_code)]
pub fn combinations(n: usize, r: usize) -> Box<Iterator<Item = Vec<u8>>> {
    fn inner(
        array: Vec<u8>,
        depth: usize,
        min: usize,
        max: usize,
    ) -> Box<Iterator<Item = Vec<u8>>> {
        let na = (min..(max - depth)).map(move |x| {
            let mut newarray = array.clone();
            newarray.push(x as u8);
            newarray
        });
        if depth > 0 {
            Box::new(na.flat_map(move |x| {
                let next = usize::from(*x.last().unwrap()) + 1;
                inner(x, depth - 1, next, max)
            }))
        } else {
            Box::new(na)
        }
    }
    inner(Vec::new(), r - 1, 0, n)
}


Measured memory_bytes: 12540