#include <bits/stdc++.h>
using namespace std;
int N,M;
int mod;
int l,h;
vector<pair<int,int>> v;
vector<pair<int,int>> ro;
vector<pair<int,int>> oh;
int mepu[500100];
int total[500100];
bool usable[500100];
int mapping[500100];
struct node{
int s,e,m;
long long int v;
node *l,*r;
node(int S, int E){
s = S;
e = E;
m = (s + e)/2;
v = 1;
if(s != e){
l = new node(s,m);
r = new node(m + 1, e);
}
}
void update(int i, int k){
if(s == e){
v += k;
return;
}
if(i <= m){
l -> update(i,k);
}
else{
r -> update(i,k);
}
v = (l -> v * r -> v) % mod;
}
int query(int S, int E){
if(E < S) return 1;
if(S <= s && e <= E){
return v;
}
long long int V = 1;
if(S <= m){
V *= l -> query(S,E);
}
if(m < E){
V *= r -> query(S,E);
}
return V % mod;
}
}*root,*lroot;
int main(){
scanf(" %d",&N);
scanf(" %d",&M);
scanf(" %d",&mod);
int next[500100];
for(int i = 1; i <= M; i++){
mepu[i] = -1;
total[i] = 0;
next[i] = -1;
}
for(int i = 0; i <= M; i++) usable[i] = false;
for(int i = 0; i < N; i++){
scanf(" %d",&l);
scanf(" %d",&h);
v.push_back(make_pair(l,h));
}
sort(v.begin(),v.end(),greater<pair<int,int>>());
bool o[500100];
bool o1[500100];
for(int i = 0; i <= M; i++){
o[i] = true;
o1[i] = true;
}
for(int i = 0; i < v.size(); i++){
if(o[v[i].second]){
oh.push_back(v[i]);
o[v[i].second] = false;
}
else if(o1[v[i].second]){
next[v[i].second] = v[i].first;
o1[v[i].second] = false;
}
}
root = new node(0,M);
lroot = new node(0,M);
int it = oh.size() - 1;
int it1 = 0;
ro = oh;
reverse(ro.begin(),ro.end());
for(int i = 0; i < ro.size(); i++){
mapping[ro[i].second] = i;
}
reverse(v.begin(),v.end());
int bigans = 0;
for(int i = 0; i < N; i++){
total[v[i].second]++;
while(it != N && v[i].first >= v[it].first * 2){
lroot -> update(mapping[v[it].second], 1);
if(usable[v[it].second]){
root -> update(mapping[v[it].second],1);
it++;
}
else{
if(mepu[v[it].second] == -1){
mepu[v[it].second] = 1;
}
else{
mepu[v[it].second]++;
}
it++;
}
}
if(v[i] == oh.back()){
if(mepu[oh.back().second] != -1){
root -> update(mapping[oh.back().second],mepu[oh.back().second] - 1);
}
usable[oh.back().second] = true;
bigans += root -> query(0,N - oh.size());
bigans %= mod;
oh.pop_back();
if(next[v[it].second] == -1){
pair<int,int> f = *lower_bound(oh.begin(),oh.end(),make_pair(v[i].first * 2 - 1, -1));
bigans += lroot -> query(0,mapping[f.second]);
}
else{
int s = lower_bound(ro.begin(),ro.end(),make_pair(min(v[i].first,next[v[i].first] * 2) , 1100100100)) -> second;
int e = lower_bound(oh.begin(),oh.end(),make_pair(v[i].first * 2 - 1, -1)) -> second;
printf("%d %d\n",s,e);
bigans += (lroot -> query(mapping[max(s,v[it].second - 1)],mapping[e]) - 1) * (long long int) (lroot -> query(0,mapping[v[i].second] - 1 ) );
}
//bigans += lroot -> query(1,v[i].second - 1) * (long long int) lroot -> query(v[i].second + 1, M);
bigans %= mod;
printf("%d %d %d %d\n",v[i].first,bigans,lroot -> query(1,v[i].second - 1) , (long long int) lroot -> query(v[i].second + 1, M));
}
}
printf("%d",bigans);
}
/*
*
5
3
700
8 3
7 2
4 1
2 3
2 2
*
*/