#include<bits/stdc++.h>
#define ll long long
#define rep(i, a, b) for(int i = a; i < b; ++i)
#define per(i, a, b) for(int i = a - 1; i >= b; --i)
#define vi vector<int>
#define vvi vector<vector<int> >
#define pii pair<int, int>
#define piii pair<int,pair<int, int> >
#define pb push_back
#define mp make_pair
#define lb lower_bound
#define ub upper_bound
#define F first
#define S second
#define SPD ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;

int main(){
    SPD;
    int n,l,w;cin>>n>>l>>w;
    vector<int>a;
    vector<double>b;
    if(w==1){
        ll rs=0;
        ll rs2=0;
        rep(i,0,n){
            int c,v;cin>>c>>v;
            if(v==1)rs+=c<0;
            else rs2+=((c+l)>0);
        }
        cout<<rs*rs2;
        return 0;
    }
    rep(i,0,n){
        int c,v;cin>>c>>v;
        if(v==-1)a.pb(c+l);
        else {
            if(c<=0)b.pb(1.0*c/(w+1)*w);
            else b.pb(1.0*c/(w-1)*w);
        }
    }
    ll rs=0;
    sort(b.begin(),b.end());
    rep(i,0,a.size()){
        double tmp;
        if(a[i]<=0)tmp=1.0*a[i]/(w-1)*w;
        else tmp=1.0*a[i]/(w+1)*w;
        rs+=lb(b.begin(),b.end(),tmp)-b.begin();
    }
    cout<<rs;
    return 0;
}


#include <cstdio>
#include <cstring>

#include <algorithm>
#include <functional>

#define LOG(FMT...) fprintf(stderr, FMT)

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

struct Frac {
	int x, y;

	Frac() {}

	Frac(int x, int y) : x(x), y(y) {}

	bool operator<(const Frac& rhs) const { return x * (ll)rhs.y < rhs.x * (ll)y; }
	bool operator>(const Frac& rhs) const { return rhs < *this; }
};

const int N = 100010;

ll ans;
int n, l, w;
int plc, prc, nlc, nrc;
int plx[N], prx[N], nlx[N], nrx[N];
int fw[N];
pair<int, int> lseg[N], rseg[N];

void calc(pair<int, int>*, int n);
int lowBit(int x);
void change(int k);
int query(int k);

int main() {
	scanf("%d%d%d", &n, &l, &w);
	int specv = 0;
	for (int i = 1; i <= n; ++i) {
		int x, v;
		scanf("%d%d", &x, &v);
		if (x > -l && x < 0) {
			specv = v;
		}
		if (v == 1) {
			if (x <= -l) {
				plx[++plc] = x;
				lseg[plc + nlc] = make_pair(x, v);
			} else {
				prx[++prc] = x;
				rseg[prc + nrc] = make_pair(x, v);
			}
		} else {
			if (x <= -l) {
				x += l;
				nlx[++nlc] = x;
				lseg[plc + nlc] = make_pair(x, v);
			} else {
				x += l;
				nrx[++nrc] = x;
				rseg[prc + nrc] = make_pair(x, v);
			}
		}
	}
	if (specv == 1)
		ans += nrc;
	else if (specv == -1)
		ans += plc;
	ans += (ll)plc * nrc;
	if (w == 1) {
		printf("%lld\n", ans);
		return 0;
	}
	int lc = plc + nlc, rc = prc + nrc;
	sort(lseg + 1, lseg + lc + 1);
	for (int i = 1; i <= rc; ++i) {
		rseg[i].first *= -1;
		rseg[i].second *= -1;
	}
	sort(rseg + 1, rseg + rc + 1);
	calc(lseg, lc);
	calc(rseg, rc);
	printf("%lld\n", ans);
	return 0;
}

int lowBit(int x) {
	return x & -x;
}

void change(int k) {
	for (; k <= n; k += lowBit(k))
		++fw[k];
}

int query(int k) {
	int ret = 0;
	for (; k; k -= lowBit(k))
		ret += fw[k];
	return ret;
}

void calc(pair<int, int>* arr, int n) {
	memset(fw, 0, sizeof(fw));
	static Frac ff[N];
	for (int i = 1; i <= n; ++i)
		if (arr[i].second == 1)
			ff[i] = Frac(-arr[i].first - l, w + 1);
		else
			ff[i] = Frac(-arr[i].first, w - 1);
	sort(ff + 1, ff + n + 1);
	for (int i = 1; i <= n; ++i) {
		int ind;
		if (arr[i].second == 1) {
			ind = lower_bound(ff + 1, ff + n + 1, Frac(-arr[i].first - l, w + 1)) - ff;
			ind = n - ind + 1;
			change(ind);
		} else {
			ind = lower_bound(ff + 1, ff + n + 1, Frac(-arr[i].first, w - 1)) - ff;
			ind = n - ind + 1;
			ans += query(ind);
		}
	}
}


#include <cstdio>
#include <cstring>

#include <algorithm>
#include <functional>

#define LOG(FMT...) fprintf(stderr, FMT)

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

struct Frac {
	int x, y;

	Frac() {}

	Frac(int x, int y) : x(x), y(y) {}

	bool operator<(const Frac& rhs) const { return x * (ll)rhs.y < rhs.x * (ll)y; }
	bool operator>(const Frac& rhs) const { return rhs < *this; }
};

const int N = 100010;

ll ans;
int n, l, w;
int plc, prc, nlc, nrc;
int plx[N], prx[N], nlx[N], nrx[N];
int fw[N];
pair<int, int> lseg[N], rseg[N];

void calc(pair<int, int>*, int n);
int lowBit(int x);
void change(int k);
int query(int k);

int main() {
	scanf("%d%d%d", &n, &l, &w);
	int specv = 0;
	for (int i = 1; i <= n; ++i) {
		int x, v;
		scanf("%d%d", &x, &v);
		if (x > -l && x < 0) {
			specv = v;
			continue;
		}
		if (v == 1) {
			if (x <= -l) {
				plx[++plc] = x;
				lseg[plc + nlc] = make_pair(x, v);
			} else {
				x += l;
				prx[++prc] = x;
				rseg[prc + nrc] = make_pair(x, v);
			}
		} else {
			if (x <= -l) {
				nlx[++nlc] = x;
				lseg[plc + nlc] = make_pair(x, v);
			} else {
				x += l;
				nrx[++nrc] = x;
				rseg[prc + nrc] = make_pair(x, v);
			}
		}
	}
	if (specv == 1)
		ans += nrc;
	else if (specv == -1)
		ans += plc;
	ans += (ll)plc * nrc;
	if (w == 1) {
		printf("%lld\n", ans);
		return 0;
	}
	int lc = plc + nlc, rc = prc + nrc;
	sort(lseg + 1, lseg + lc + 1);
	for (int i = 1; i <= rc; ++i) {
		rseg[i].first *= -1;
		rseg[i].second *= -1;
	}
	sort(rseg + 1, rseg + rc + 1);
	calc(lseg, lc);
	calc(rseg, rc);
	printf("%lld\n", ans);
	return 0;
}

int lowBit(int x) {
	return x & -x;
}

void change(int k) {
	for (; k <= n; k += lowBit(k))
		++fw[k];
}

int query(int k) {
	int ret = 0;
	for (; k; k -= lowBit(k))
		ret += fw[k];
	return ret;
}

void calc(pair<int, int>* arr, int n) {
//	puts("STSRT");
	memset(fw, 0, sizeof(fw));
	static Frac ff[N];
	for (int i = 1; i <= n; ++i)
		if (arr[i].second == 1)
			ff[i] = Frac(-arr[i].first, w + 1);
		else
			ff[i] = Frac(-arr[i].first - l, w - 1);
	sort(ff + 1, ff + n + 1);
	for (int i = 1; i <= n; ++i) {
		int ind;
		if (arr[i].second == 1) {
			ind = lower_bound(ff + 1, ff + n + 1, Frac(-arr[i].first, w + 1)) - ff;
//			printf("%d/%d", -arr[i].first - l, w + 1);
//			ind = n - ind + 1;
			change(ind);
		} else {
			ind = lower_bound(ff + 1, ff + n + 1, Frac(-arr[i].first - l, w - 1)) - ff;
//			printf("%d/%d", -arr[i].first, w - 1);
//			ind = n - ind + 1;
//			printf("%d %d: %d\n", arr[i].first, arr[i].second, query(ind - 1));
			ans += query(ind - 1);
		}
//		printf("POS %d\n", ind);
	}
}


#include <cstdio>
#include <cstring>

#include <algorithm>
#include <functional>

#define LOG(FMT...) fprintf(stderr, FMT)

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

struct Frac {
	int x, y;

	Frac() {}

	Frac(int x, int y) : x(x), y(y) {}

	bool operator<(const Frac& rhs) const { return x * (ll)rhs.y < rhs.x * (ll)y; }
	bool operator>(const Frac& rhs) const { return rhs < *this; }
};

const int N = 100010;

ll ans;
int n, l, w;
int plc, prc, nlc, nrc;
int plx[N], prx[N], nlx[N], nrx[N];
int fw[N];
pair<int, int> lseg[N], rseg[N];

void calc(pair<int, int>*, int n);
int lowBit(int x);
void change(int k);
int query(int k);

int main() {
	scanf("%d%d%d", &n, &l, &w);
	int specv = 0;
	for (int i = 1; i <= n; ++i) {
		int x, v;
		scanf("%d%d", &x, &v);
		if (x > -l && x < 0) {
			specv = v;
			continue;
		}
		if (v == 1) {
			if (x <= -l) {
				plx[++plc] = x;
				lseg[plc + nlc] = make_pair(x, v);
			} else {
				x += l;
				prx[++prc] = x;
				rseg[prc + nrc] = make_pair(x, v);
			}
		} else {
			if (x <= -l) {
				nlx[++nlc] = x;
				lseg[plc + nlc] = make_pair(x, v);
			} else {
				x += l;
				nrx[++nrc] = x;
				rseg[prc + nrc] = make_pair(x, v);
			}
		}
	}
	if (specv == 1)
		ans += nrc;
	else if (specv == -1)
		ans += plc;
	ans += (ll)plc * nrc;
	if (w == 1) {
		printf("%lld\n", ans);
		return 0;
	}
	int lc = plc + nlc, rc = prc + nrc;
	sort(lseg + 1, lseg + lc + 1);
	for (int i = 1; i <= rc; ++i) {
		rseg[i].first *= -1;
		rseg[i].second *= -1;
	}
	sort(rseg + 1, rseg + rc + 1);
	calc(lseg, lc);
	calc(rseg, rc);
	printf("%lld\n", ans);
	return 0;
}

int lowBit(int x) {
	return x & -x;
}

void change(int k) {
	for (; k <= n; k += lowBit(k))
		++fw[k];
}

int query(int k) {
	int ret = 0;
	for (; k; k -= lowBit(k))
		ret += fw[k];
	return ret;
}

void calc(pair<int, int>* arr, int n) {
//	puts("STSRT");
	memset(fw, 0, sizeof(fw));
	static Frac ff[N];
	for (int i = 1; i <= n; ++i)
		if (arr[i].second == 1)
			ff[i] = Frac(-arr[i].first, w + 1);
		else
			ff[i] = Frac(-arr[i].first - l, w - 1);
	sort(ff + 1, ff + n + 1);
	for (int i = 1; i <= n; ++i) {
		int ind;
		if (arr[i].second == 1) {
			ind = lower_bound(ff + 1, ff + n + 1, Frac(-arr[i].first, w + 1)) - ff;
//			printf("%d/%d", -arr[i].first - l, w + 1);
			ind = n - ind + 1;
			change(ind);
		} else {
			ind = lower_bound(ff + 1, ff + n + 1, Frac(-arr[i].first - l, w - 1)) - ff;
//			printf("%d/%d", -arr[i].first, w - 1);
			ind = n - ind + 1;
//			printf("%d %d: %d\n", arr[i].first, arr[i].second, query(ind - 1));
			ans += query(ind - 1);
		}
//		printf("POS %d\n", ind);
	}
}


#include <cstdio>
#include <cstring>

#include <algorithm>
#include <functional>

#define LOG(FMT...) fprintf(stderr, FMT)

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

struct Frac {
	int x, y;

	Frac() {}

	Frac(int x, int y) : x(x), y(y) {}

	bool operator<(const Frac& rhs) const { return x * (ll)rhs.y < rhs.x * (ll)y; }
	bool operator>(const Frac& rhs) const { return rhs < *this; }
};

const int N = 100010;

ll ans;
int n, l, w;
int plc, prc, nlc, nrc;
int plx[N], prx[N], nlx[N], nrx[N];
int fw[N];
pair<int, int> lseg[N], rseg[N];

void calc(pair<int, int>*, int n);
int lowBit(int x);
void change(int k);
int query(int k);

int main() {
	scanf("%d%d%d", &n, &l, &w);
	int specv = 0;
	for (int i = 1; i <= n; ++i) {
		int x, v;
		scanf("%d%d", &x, &v);
		if (x > -l && x < 0) {
			specv = v;
			continue;
		}
		if (v == 1) {
			if (x <= -l) {
				plx[++plc] = x;
				lseg[plc + nlc] = make_pair(x, v);
			} else {
				prx[++prc] = x;
				rseg[prc + nrc] = make_pair(x, v);
			}
		} else {
			if (x <= -l) {
				x += l;
				nlx[++nlc] = x;
				lseg[plc + nlc] = make_pair(x, v);
			} else {
				x += l;
				nrx[++nrc] = x;
				rseg[prc + nrc] = make_pair(x, v);
			}
		}
	}
	if (specv == 1)
		ans += nrc;
	else if (specv == -1)
		ans += plc;
	ans += (ll)plc * nrc;
	if (w == 1) {
		printf("%lld\n", ans);
		return 0;
	}
	int lc = plc + nlc, rc = prc + nrc;
	sort(lseg + 1, lseg + lc + 1);
	for (int i = 1; i <= rc; ++i) {
		rseg[i].first *= -1;
		rseg[i].second *= -1;
	}
	sort(rseg + 1, rseg + rc + 1);
	calc(lseg, lc);
	calc(rseg, rc);
	printf("%lld\n", ans);
	return 0;
}

int lowBit(int x) {
	return x & -x;
}

void change(int k) {
	for (; k <= n; k += lowBit(k))
		++fw[k];
}

int query(int k) {
	int ret = 0;
	for (; k; k -= lowBit(k))
		ret += fw[k];
	return ret;
}

void calc(pair<int, int>* arr, int n) {
	memset(fw, 0, sizeof(fw));
	static Frac ff[N];
	for (int i = 1; i <= n; ++i)
		if (arr[i].second == 1)
			ff[i] = Frac(-arr[i].first - l, w + 1);
		else
			ff[i] = Frac(-arr[i].first, w - 1);
	sort(ff + 1, ff + n + 1);
	for (int i = 1; i <= n; ++i) {
		int ind;
		if (arr[i].second == 1) {
			ind = lower_bound(ff + 1, ff + n + 1, Frac(-arr[i].first - l, w + 1)) - ff;
			ind = n - ind + 1;
			change(ind);
		} else {
			ind = lower_bound(ff + 1, ff + n + 1, Frac(-arr[i].first, w - 1)) - ff;
			ind = n - ind + 1;
//			printf("%d %d: %d\n", arr[i].first, arr[i].second, query(ind - 1));
			ans += query(ind - 1);
		}
	}
}


#include <cstdio>
#include <cstring>

#include <algorithm>
#include <functional>

#define LOG(FMT...) fprintf(stderr, FMT)

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

struct Frac {
	int x, y;

	Frac() {}

	Frac(int x, int y) : x(x), y(y) {}

	bool operator<(const Frac& rhs) const { return x * (ll)rhs.y < rhs.x * (ll)y; }
	bool operator>(const Frac& rhs) const { return rhs < *this; }
};

const int N = 100010;

ll ans;
int n, l, w;
int plc, prc, nlc, nrc;
int plx[N], prx[N], nlx[N], nrx[N];
int fw[N];
pair<int, int> lseg[N], rseg[N];

void calc(pair<int, int>*, int n);
int lowBit(int x);
void change(int k);
int query(int k);

int main() {
	scanf("%d%d%d", &n, &l, &w);
	int specv = 0;
	for (int i = 1; i <= n; ++i) {
		int x, v;
		scanf("%d%d", &x, &v);
		if (x > -l && x < 0) {
			specv = v;
		}
		if (v == 1) {
			if (x <= -l) {
				plx[++plc] = x;
				lseg[plc + nlc] = make_pair(x, v);
			} else {
				prx[++prc] = x;
				rseg[prc + nrc] = make_pair(x, v);
			}
		} else {
			if (x <= -l) {
				x += l;
				nlx[++nlc] = x;
				lseg[plc + nlc] = make_pair(x, v);
			} else {
				x += l;
				nrx[++nrc] = x;
				rseg[prc + nrc] = make_pair(x, v);
			}
		}
	}
	if (specv == 1)
		ans += nrc;
	else if (specv == -1)
		ans += plc;
	ans += (ll)plc * nrc;
	if (w == 1) {
		printf("%lld\n", ans);
		return 0;
	}
	int lc = plc + nlc, rc = prc + nrc;
	sort(lseg + 1, lseg + lc + 1);
	for (int i = 1; i <= rc; ++i) {
		rseg[i].first *= -1;
		rseg[i].second *= -1;
	}
	sort(rseg + 1, rseg + rc + 1);
	calc(lseg, lc);
	calc(rseg, rc);
	printf("%lld\n", ans);
	return 0;
}

int lowBit(int x) {
	return x & -x;
}

void change(int k) {
	for (; k <= n; k += lowBit(k))
		++fw[k];
}

int query(int k) {
	int ret = 0;
	for (; k; k -= lowBit(k))
		ret += fw[k];
	return ret;
}

void calc(pair<int, int>* arr, int n) {
	memset(fw, 0, sizeof(fw));
	static Frac ff[N];
	for (int i = 1; i <= n; ++i)
		if (arr[i].second == 1)
			ff[i] = Frac(-arr[i].first - l, w + 1);
		else
			ff[i] = Frac(-arr[i].first, w - 1);
	sort(ff + 1, ff + n + 1);
	for (int i = 1; i <= n; ++i) {
		int ind;
		if (arr[i].second == 1) {
			ind = lower_bound(ff + 1, ff + n + 1, Frac(-arr[i].first - l, w + 1)) - ff;
			ind = n - ind + 1;
			change(ind);
		} else {
			ind = lower_bound(ff + 1, ff + n + 1, Frac(-arr[i].first, w - 1)) - ff;
			ind = n - ind + 1;
			ans += query(ind - 1);
		}
	}
}


#include <bits/stdc++.h>
using namespace std;

#define PI 3.141592653589793238462643383279
const long double EPS = 1e-9;
const long long MOD = 1e9+7;
#define N 100100
pair<long long, int> inp[N];
int right_dir_sum[N], left_dir_sum[N];

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout << setprecision(20);
    #ifdef LOCAL_TEST
    freopen("input.txt","r",stdin);
    #endif
    int n; cin >> n;
    long long l, w; cin >> l >> w;
    for(int i=0;i<n;i++) cin >> inp[i].first >> inp[i].second;
    sort(inp, inp + n);
    int last_neg = -1;
    for(int i=0;i<n;i++){
        if(inp[i].first < 0) last_neg = i;
        else break;
    }
    int first_pos = last_neg + 1;

    for(int i=0;i<n;i++){
        right_dir_sum[i+1] = right_dir_sum[i] + (inp[i].second == 1);
        left_dir_sum[i+1] = left_dir_sum[i] + (inp[i].second == -1);
    }

    long long ans = 0;
    for(int i=first_pos, j = first_pos;i<n;i++){
        if(inp[i].second == 1) continue;
        ans += right_dir_sum[first_pos];
        while(j < i && inp[j].first * (w + 1) < (w-1) * (inp[i].first + l)) j++;
        ans += right_dir_sum[j] - right_dir_sum[first_pos];
        // int lo = first_pos, hi = i - 1;
        // while(lo <= hi){
        //     int mid = lo + (hi - lo) / 2;
        //     if((inp[mid].first + l) * (w + 1) >= inp[i].first * (w - 1)) hi = mid - 1;
        //     else lo = mid + 1;
        // }
        // ans += right_dir_sum[i] - right_dir_sum[hi + 1];
        // cout << ans << ' ' << j << endl;
    }

    for(int i=last_neg,j=last_neg;i>=0;i--){
        if(inp[i].second == -1) continue;
        // ans += left_dir_sum[n] - left_dir_sum[last_neg + 1];
        while(j > i && (-inp[j].first - l) * (w + 1) < (-inp[i].first) * (w - 1)) j--;
        ans += left_dir_sum[last_neg + 1] - left_dir_sum[j + 1];
        // int lo = i + 1, hi = last_neg;
        // while(lo <= hi){
        //     int mid = lo + (hi - lo) / 2;
        //     if((l - inp[mid].first) * (w + 1) >= -inp[i].first * (w - 1)) lo = mid + 1;
        //     else hi = mid - 1;
        // }
        // ans += left_dir_sum[lo] - left_dir_sum[i+1];
    }

    cout << ans << '\n';
}


#include <bits/stdc++.h>
using namespace std;
vector<int64_t> pos,neg;
int64_t n,wmax,l,ans,x,v,low,mid,high;
bool check(int64_t x1,int64_t x2){
	return ((wmax+1)*x2>(wmax-1)*x1) && ((wmax-1)*x2>(wmax+1)*x1);
}
int main(){
	for(cin>>n>>l>>wmax;n--&&cin>>x>>v;(v>0?pos:neg).push_back(v<0?x+l:x));
	sort(neg.begin(),neg.end());
	for(auto i:pos){
		for(low=0,high=neg.size();low<high;check(i,neg[mid=low+high>>1])?high=mid:low=mid+1);
		ans+=neg.size()-low;
	}
	cout<<ans;
}


/*input
5 1 2
-2 1
2 1
3 -1
5 -1
7 -1
*/
#include <bits/stdc++.h>
using namespace std;
vector<int> pos,neg;
int n,wmax,l;
vector<pair<int,int>> a[2][2];
bool check(long long x1,long long x2){
	return (x1<x2) && ((wmax+1)*x2>(wmax-1)*x1) && ((wmax-1)*x2>(wmax+1)*x1);
}
int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	long long ans=0;
	cin>>n>>l>>wmax;
	for(int i=0,x,v;i<n;++i){
		cin>>x>>v;
		if(v>0) pos.push_back(x);
		else neg.push_back(x+l);
	}
	sort(neg.begin(),neg.end());
	for(auto i:pos){
		int low=0,high=neg.size(),mid;
		while(low<high)
			if(check(i,neg[mid=low+high>>1])) high=mid;
			else low=mid+1;
		//cout<<i<<' '<<low<<'\n';
		ans += neg.size() - low;
	}
	cout<<ans;
}


#include <bits/stdc++.h>

using namespace std;
using ll = long long;

int l, n, w;
int const N = 200200;
int a[N];
int b[N];

bool check(int ia, int ib) {
    if (a[ia] + l <= b[ib]) {
        return false;
    }
    int t = (a[ia] + l - b[ib]);
    bool ans = abs(2 * b[ib] + t) < w * t;
    // cerr << ia << ' ' << ib << ' ' << ans << endl;
    return ans;
}

void solve() {
    cin >> n >> l >> w;
    int na = 0;
    int nb = 0;
    for (int i = 0; i < n; ++i) {
        int x, y;
        cin >> x >> y;
        if (y == -1) {
            a[na++] = x;
        } else {
            b[nb++] = x;
        }
    }
    sort(a, a + na);
    sort(b, b + nb);
    // for (int i = 0; i < na; ++i) {
    //     cerr << a[i] << ' ';
    // }
    // cerr << endl;
    // for (int i = 0; i < nb; ++i) {
    //     cerr << b[i] << ' ';
    // }
    // cerr << endl;
    int ib = 0;
    ll ans = 0;
    for (int ia = 0; ia < na; ++ia) {
        while (ib < nb && check(ia, ib)) ib++;
        ans += ib;
    }
    cout << ans << endl;
}

int main() {
    ios::sync_with_stdio(false);
    int tests = 1;
    // cin >> tests;
    for (int test = 0; test < tests; ++test) {
        solve();
    }
}


#include <bits/stdc++.h>

using namespace std;
using ll = long long;

int l, n, w, na, nb;
int const N = 200200;
int a[N];
int b[N];

bool check(int ia, int ib) {
    if (a[ia] + l <= b[ib]) {
        return false;
    }
    int t = (a[ia] + l - b[ib]);
    bool ans = abs(2 * b[ib] + t) < (ll)w * t;
    // cerr << ia << ' ' << ib << ' ' << ans << endl;
    return ans;
}

void read() {
    cin >> n >> l >> w;
    na = 0, nb = 0;
    for (int i = 0; i < n; ++i) {
        int x, y;
        cin >> x >> y;
        if (y == -1) {
            a[na++] = x;
        } else {
            b[nb++] = x;
        }
    }
    sort(a, a + na);
    sort(b, b + nb);
}

ll solve() {

    // for (int i = 0; i < na; ++i) {
    //     cerr << a[i] << ' ';
    // }
    // cerr << endl;
    // for (int i = 0; i < nb; ++i) {
    //     cerr << b[i] << ' ';
    // }
    // cerr << endl;
    int ib = 0;
    ll ans = 0;
    for (int ia = 0; ia < na; ++ia) {
        while (ib < nb && check(ia, ib)) ib++;
        ans += ib;
    }
    return ans;
}

ll stupid() {
    ll ans = 0;
    for (int i = 0; i < na; ++i) {
        for (int j = 0; j < nb; ++j) {
            ans += check(i, j) ? 1 : 0;
        }
    }
    return ans;
}

int main() {
    ios::sync_with_stdio(false);
    int tests = 1;
    // cin >> tests;
    for (int test = 0; test < tests; ++test) {
        read();
        ll ans = solve();
//        assert(ans == stupid());
        // cout << test << ' ' << ans << endl;
        cout << ans << endl;
    }
}


#include <bits/stdc++.h>
#define FOR(i,s,e) for(int i=(s);i<=(e);i++)
#define FORD(i,s,e) for(int i=(s);i>=(e);i--)
#define ALL(k) (k).begin(),(k).end()
#define e1 first
#define e2 second
#define mp make_pair
#define pb push_back
#define eb emplace_back

using namespace std;
typedef long long LL;
typedef unsigned long long LLU;
typedef long double LD;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef vector<int> VI;
const bool print=false;
const long double epsilon = 1e-8;
const int N=57;
const LL mod=1e9+7;

int main(){
	vector<long double> towardsRight, towardsLeft;
	int n,l,w;
	cin>>n>>l>>w;
	int x,y;
	FOR(i,0,n-1){
		cin>>x>>y;
		if(y == -1){
			towardsLeft.pb(x);
		}
		else{
			towardsRight.pb(x);
		}
	}

	sort(ALL(towardsRight));
	sort(ALL(towardsLeft));

	int leftMost=0;
	LL ans=0, p=towardsLeft.size();
	for(int xCor : towardsRight){
		while(1){
			if(leftMost == p){
				cout<<ans<<"\n";
				return 0;
			}

			if(xCor > towardsLeft[leftMost]){
				leftMost++;
				continue;
			}
			int xCorLeft = towardsLeft[leftMost];
			if(xCorLeft<0 && xCorLeft+l>0){
				break;
			}
			long double xp = xCorLeft+l;
			long double timeTaken = (xp - xCor)/2.0;
			if(abs(xp/timeTaken - 1)+epsilon > w){
				leftMost++;
			}
			else{
				break;
			}
		}
		ans += (p-leftMost);
	}
	cout<<ans<<"\n";
}


#include <bits/stdc++.h>
#define FOR(i,s,e) for(int i=(s);i<=(e);i++)
#define FORD(i,s,e) for(int i=(s);i>=(e);i--)
#define ALL(k) (k).begin(),(k).end()
#define e1 first
#define e2 second
#define mp make_pair
#define pb push_back
#define eb emplace_back

using namespace std;
typedef long long LL;
typedef unsigned long long LLU;
typedef long double LD;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef vector<int> VI;
const bool print=false;
const double epsilon = 1e-6;
const int N=57;
const LL mod=1e9+7;

int main(){
	vector<int> towardsRight, towardsLeft;
	int n,l,w;
	cin>>n>>l>>w;
	int x,y;
	FOR(i,0,n-1){
		cin>>x>>y;
		if(y == -1){
			towardsLeft.pb(x);
		}
		else{
			towardsRight.pb(x);
		}
	}

	sort(ALL(towardsRight));
	sort(ALL(towardsLeft));

	int leftMost=0;
	LL ans=0, p=towardsLeft.size();
	for(int xCor : towardsRight){
		while(1){
			if(leftMost == p){
				cout<<ans<<"\n";
				return 0;
			}

			if(xCor > towardsLeft[leftMost]){
				leftMost++;
				continue;
			}
			int xCorLeft = towardsLeft[leftMost];
			if(xCorLeft<0 && xCorLeft+l>0){
				break;
			}
			double xp = xCorLeft+l;
			double timeTaken = (xp - xCor)/2.0;
			if(abs(xp/timeTaken - 1)+epsilon > w){
				leftMost++;
			}
			else{
				break;
			}
		}
		ans += p-leftMost;
	}
	cout<<ans<<"\n";
}


#include <bits/stdc++.h>
#define FOR(i,s,e) for(int i=(s);i<=(e);i++)
#define FORD(i,s,e) for(int i=(s);i>=(e);i--)
#define ALL(k) (k).begin(),(k).end()
#define e1 first
#define e2 second
#define mp make_pair
#define pb push_back
#define eb emplace_back

using namespace std;
typedef long long LL;
typedef unsigned long long LLU;
typedef long double LD;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef vector<int> VI;
const bool print=false;
const double epsilon = 1e-6;
const int N=57;
const LL mod=1e9+7;

int main(){
	vector<double> towardsRight, towardsLeft;
	int n,l,w;
	cin>>n>>l>>w;
	int x,y;
	FOR(i,0,n-1){
		cin>>x>>y;
		if(y == -1){
			towardsLeft.pb(x);
		}
		else{
			towardsRight.pb(x);
		}
	}

	sort(ALL(towardsRight));
	sort(ALL(towardsLeft));

	int leftMost=0;
	LL ans=0, p=towardsLeft.size();
	for(int xCor : towardsRight){
		while(1){
			if(leftMost == p){
				cout<<ans<<"\n";
				return 0;
			}

			if(xCor > towardsLeft[leftMost]){
				leftMost++;
				continue;
			}
			int xCorLeft = towardsLeft[leftMost];
			if(xCorLeft<0 && xCorLeft+l>0){
				break;
			}
			long double xp = xCorLeft+l;
			long double timeTaken = (xp - xCor)/2.0;
			if(abs(xp/timeTaken - 1)+epsilon > w){
				leftMost++;
			}
			else{
				break;
			}
		}
		ans += (p-leftMost);
	}
	cout<<ans<<"\n";
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int limN = 1e5 + 5;

ll maxW, L ;
int N ;
vector <int> ders, izqs;

bool funca(ll xi, ll xj) {
    ll t2 = xj-xi;
    if( min(abs(-xi*2 - t2),
           abs((-xj-L)*2 + t2)) < t2*maxW)
        return true;
    t2 = xj-(xi + L);
    if( min(abs(-xi*2 - t2),
            abs((-xj-L)*2 + t2)) < t2*maxW )
        return true;
    t2 = xj+L-xi;
    return min(abs(-xi*2 - t2),
               abs((-xj-L)*2 + t2)) < t2*maxW;
}

ll calcaPs(ll xi, int ini) {
    if(ini == N) return 0;
    int fin = N, piv;
    // printf("%lld %d\n", xi, ini);
    while(ini < fin) {
        piv = (ini+fin)/2;
        if(funca(xi, izqs[piv]))
            fin = piv;
        else
            ini = piv+1;
    }
    // printf("%lld => %d %d\n", xi, ini, ini==N?  (int) -1e9 : izqs[ini]);
    if(ini < N) {
        // double t =
    }
    return N-ini;
}

int main() {
    ll ans = 0;

    scanf("%d%lld%lld", &N, &L, &maxW);
    for(int i=0, a,b; i<N; i++) {
        scanf("%d%d", &a, &b);
        if(b==-1)
            izqs.push_back(a);
        else
            ders.push_back(a);
    }
    sort(izqs.begin(), izqs.end());
    sort(ders.begin(), ders.end());

    N = izqs.size();
    int lp = 0;

    for(const int p : ders) {
        while(lp < N  &&  izqs[lp] < p)
            lp ++;
        ans += calcaPs(p, lp);
    }

    printf("%lld\n", ans);
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int limN = 1e5 + 5;

ll maxW, L ;
int N ;
vector <int> ders, izqs;

bool funca(ll xi, ll xj) {
    ll t2 = xj+L-xi;
    return min(abs(-xi*2 - t2),
               abs((-xj-L)*2 + t2)) < t2*maxW;
}

int main() {
    ll ans = 0;

    scanf("%d%lld%lld", &N, &L, &maxW);
    for(int i=0, a,b; i<N; i++) {
        scanf("%d%d", &a, &b);
        if(b==-1)
            izqs.push_back(a);
        else
            ders.push_back(a);
    }
    sort(izqs.begin(), izqs.end());
    sort(ders.begin(), ders.end());

    N = izqs.size();
    int lp = 0;

    for(const int p : ders) {
        while(lp < N  &&  (izqs[lp] < p  || !funca(p, izqs[lp])) )
            lp ++;
        ans += N-lp;
    }

    printf("%lld\n", ans);
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int limN = 1e5 + 5;

ll maxW, L ;
int N ;
vector <int> ders, izqs;

bool funca(ll xi, ll xj) {
    ll t2 = xj+L-xi;
    return min(abs(-xi*2 - t2),
               abs((-xj-L)*2 + t2)) < t2*maxW;
}

ll calcaPs(ll xi, int ini) {
    if(ini == N) return 0;
    int fin = N, piv;
    // printf("%lld %d\n", xi, ini);
    while(ini < fin) {
        piv = (ini+fin)/2;
        if(funca(xi, izqs[piv]))
            fin = piv;
        else
            ini = piv+1;
    }
    // printf("%lld => %d %d\n", xi, ini, ini==N?  (int) -1e9 : izqs[ini]);
    if(ini < N) {
        // double t =
    }
    return N-ini;
}

int main() {
    ll ans = 0;

    scanf("%d%lld%lld", &N, &L, &maxW);
    for(int i=0, a,b; i<N; i++) {
        scanf("%d%d", &a, &b);
        if(b==-1)
            izqs.push_back(a);
        else
            ders.push_back(a);
    }
    sort(izqs.begin(), izqs.end());
    sort(ders.begin(), ders.end());

    N = izqs.size();
    int lp = 0;

    for(const int p : ders) {
        while(lp < N  &&  izqs[lp] < p)
            lp ++;
        ans += calcaPs(p, lp);
    }

    printf("%lld\n", ans);
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int limN = 1e5 + 5;

ll maxW, L ;
int N ;
vector <int> ders, izqs;

bool funca(ll xi, ll xj) {
    ll t2 = xj-xi;
    return min(abs(-xi*2 - t2),
               abs((-xj-L)*2 + t2)) < t2*maxW;
}

ll calcaPs(ll xi, int ini) {
    if(ini == N) return 0;
    int fin = N, piv;
    // printf("%lld %d\n", xi, ini);
    while(ini < fin) {
        piv = (ini+fin)/2;
        if(funca(xi, izqs[piv]))
            fin = piv;
        else
            ini = piv+1;
    }
    // printf("%lld => %d %d\n", xi, ini, ini==N?  (int) -1e9 : izqs[ini]);
    if(ini < N) {
        // double t =
    }
    return N-fin;
}

int main() {
    ll ans = 0;

    scanf("%d%lld%lld", &N, &L, &maxW);
    for(int i=0, a,b; i<N; i++) {
        scanf("%d%d", &a, &b);
        if(b==-1)
            izqs.push_back(a);
        else
            ders.push_back(a);
    }
    sort(izqs.begin(), izqs.end());
    sort(ders.begin(), ders.end());

    N = izqs.size();
    int lp = 0;

    for(const int p : ders) {
        while(lp < N  &&  izqs[lp] < p)
            lp ++;
        ans += calcaPs(p, lp);
    }

    printf("%lld\n", ans);
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int limN = 1e5 + 5;

ll maxW, L ;
int N ;
vector <int> ders, izqs;

bool funca(ll xi, ll xj) {
    ll t2 = xj-xi;
    if( min(abs(-xi*2 - t2),
           abs((-xj-L)*2 + t2)) < t2*maxW)
        return true;
    t2 = xj-(xi + L);
    return min(abs(-xi*2 - t2),
               abs((-xj-L)*2 + t2)) < t2*maxW;
}

ll calcaPs(ll xi, int ini) {
    if(ini == N) return 0;
    int fin = N, piv;
    // printf("%lld %d\n", xi, ini);
    while(ini < fin) {
        piv = (ini+fin)/2;
        if(funca(xi, izqs[piv]))
            fin = piv;
        else
            ini = piv+1;
    }
    // printf("%lld => %d %d\n", xi, ini, ini==N?  (int) -1e9 : izqs[ini]);
    if(ini < N) {
        // double t =
    }
    return N-ini;
}

int main() {
    ll ans = 0;

    scanf("%d%lld%lld", &N, &L, &maxW);
    for(int i=0, a,b; i<N; i++) {
        scanf("%d%d", &a, &b);
        if(b==-1)
            izqs.push_back(a);
        else
            ders.push_back(a);
    }
    sort(izqs.begin(), izqs.end());
    sort(ders.begin(), ders.end());

    N = izqs.size();
    int lp = 0;

    for(const int p : ders) {
        while(lp < N  &&  izqs[lp] < p)
            lp ++;
        ans += calcaPs(p, lp);
    }

    printf("%lld\n", ans);
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int limN = 1e5 + 5;

ll maxW, L ;
int N ;
vector <int> ders, izqs;

bool funca(ll xi, ll xj) {
    ll t2 = xj-xi;
    return min(abs(-xi*2 - t2),
               abs((-xj-L)*2 + t2)) < t2*maxW;
}

ll calcaPs(ll xi, int ini) {
    if(ini == N) return 0;
    int fin = N, piv;
    // printf("%lld %d\n", xi, ini);
    while(ini < fin) {
        piv = (ini+fin)/2;
        if(funca(xi, izqs[piv]))
            fin = piv;
        else
            ini = piv+1;
    }
    // printf("%lld => %d %d\n", xi, ini, ini==N?  (int) -1e9 : izqs[ini]);
    if(ini < N) {
        // double t =
    }
    return N-ini;
}

int main() {
    ll ans = 0;

    scanf("%d%lld%lld", &N, &L, &maxW);
    for(int i=0, a,b; i<N; i++) {
        scanf("%d%d", &a, &b);
        if(b==-1)
            izqs.push_back(a);
        else
            ders.push_back(a);
    }
    sort(izqs.begin(), izqs.end());
    sort(ders.begin(), ders.end());

    N = izqs.size();
    int lp = 0;

    for(const int p : ders) {
        while(lp < N  &&  izqs[lp] < p)
            lp ++;
        ans += calcaPs(p, lp);
    }

    printf("%lld\n", ans);
}


#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
long long ans;
int n,l,w,x,pn;
vector <int> pos,neg;
int cal(long long a,int b){
    if (b==0) return (a>0 ? INT_MAX : -INT_MAX);
    if (a<0) {
        if (a % b!=0) return (a / b - 1);
    }
    return a / b;
}
int main(){
    ios::sync_with_stdio(false);
    scanf("%d%d%d",&n,&l,&w);
    for (int i=1; i<=n; i++) {
        scanf("%d%d",&x,&pn);
        if (pn==-1) neg.push_back(x);
        else pos.push_back(x);
    }
    sort(neg.begin(),neg.end());
    sort(pos.begin(),pos.end());
    for (int i=0; i<neg.size(); i++) {
        int v=neg[i];
        auto now=lower_bound(pos.begin(),pos.end(),-v-l);
        int max1=cal((long long)(v+l) * (w+1) -1 , w - 1);
        int max2=cal((long long)(v+l) * (w-1) -1 , w + 1);
        ans+=(upper_bound(pos.begin(),now,max1)-pos.begin()-1)+
             (upper_bound(now,pos.end(),min(max2,v))-now-1);
    }
    cout<<ans<<endl;
    return 0;
}


#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#define ite vector <int>::iterator
using namespace std;
long long ans;
int n,l,w,x,pn;
vector <int> pos,neg;
int cal(long long a,int b){
    if (b==0) return (a>0 ? INT_MAX : -INT_MAX);
    if (a<0) {
        if (a % b!=0) return (a / b - 1);
    }
    return a / b;
}
int main(){
    ios::sync_with_stdio(false);
    scanf("%d%d%d",&n,&l,&w);
    for (int i=1; i<=n; i++) {
        scanf("%d%d",&x,&pn);
        if (pn==-1) neg.push_back(x);
        else pos.push_back(x);
    }
    sort(neg.begin(),neg.end());
    sort(pos.begin(),pos.end());
    for (int i=0; i<neg.size(); i++) {
        int v=neg[i];
        ite now=lower_bound(pos.begin(),pos.end(),-v-l);
        int max1=cal((long long)(v+l) * (w+1) -1 , w - 1);
        int max2=cal((long long)(v+l) * (w-1) -1 , w + 1);
        ans+=(upper_bound(pos.begin(),now,max1)-pos.begin())+
             (upper_bound(now,pos.end(),min(max2,v))-now);
        //--------------------------------------------------------
        //cout<<v<<" "<<(upper_bound(pos.begin(),now,max1)-pos.begin())+
        //     (upper_bound(now,pos.end(),min(max2,v))-now)<<endl;
        //--------------------------------------------------------
    }
    cout<<ans<<endl;
    return 0;
}


#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
long long ans;
int n,l,w,x,pn;
vector <int> pos,neg;
int cal(long long a,int b){
    if (b==0) return (a>0 ? INT_MAX : -INT_MAX);
    if (a<0) {
        if (a % b!=0) return (a / b - 1);
    }
    return a / b;
}
int main(){
    ios::sync_with_stdio(false);
    scanf("%d%d%d",&n,&l,&w);
    for (int i=1; i<=n; i++) {
        scanf("%d%d",&x,&pn);
        if (pn==-1) neg.push_back(x);
        else pos.push_back(x);
    }
    sort(neg.begin(),neg.end());
    sort(pos.begin(),pos.end());
    for (int i=0; i<neg.size(); i++) {
        int v=neg[i];
        auto now=lower_bound(pos.begin(),pos.end(),-v-l);
        int max1=cal((long long)(v+l) * (w+1) -1 , w - 1);
        int max2=cal((long long)(v+l) * (w-1) -1 , w + 1);
        ans+=(upper_bound(pos.begin(),now,max1)-pos.begin())+
             (upper_bound(now,pos.end(),min(max2,v))-now);
    }
    cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>

#define pb push_back
#define mp make_pair

#ifdef LOCAL
#define dbg(x) cerr << #x << " = " << x << endl
#define dbg2(x, y) cerr << #x << " = " << x << "; " << #y << " = " << y << ";\n"
#define dbg3(x, y, z) cerr << #x << " = " << x << "; " << #y <<  " = " << y << "; " << #z << " = " << z << ";\n"
#else
#define dbg(x)
#define dbg2(x, y)
#define dbg3(x, y, z)
#endif

using namespace std;
using ll = long long;
using pii = pair<int, int>;

int n;
double l, wmax;

vector<double> base, x;

void solve() {
	int r = 0;
	int l = 0;
	ll ans = 0;

	for (double b : base) {
		while (l < x.size() && (x[l] < b + 1e-8 || abs((x[l] + b) / (x[l] - b)) > wmax - 1e-8))
			l++;
		ans += x.size() - l;
//		dbg2(b, x[l]);
	}
	cout << ans << endl;
}

void load() {
	cin >> n >> l >> wmax;
	for (int i = 0; i < n; i++) {
		int xx, v;
		cin >> xx >> v;
		if (v > 0)
			base.push_back(xx);
		else
			x.push_back(xx + l);
	}
	sort(base.begin(), base.end());
	sort(x.begin(), x.end());
}

int main()
{
#ifndef LOCAL
	ios::sync_with_stdio(0);
	cin.tie(0);
#endif
	load();
	solve();
	return 0;
}


#include <bits/stdc++.h>

#define pb push_back
#define mp make_pair

#ifdef LOCAL
#define dbg(x) cerr << #x << " = " << x << endl
#define dbg2(x, y) cerr << #x << " = " << x << "; " << #y << " = " << y << ";\n"
#define dbg3(x, y, z) cerr << #x << " = " << x << "; " << #y <<  " = " << y << "; " << #z << " = " << z << ";\n"
#else
#define dbg(x)
#define dbg2(x, y)
#define dbg3(x, y, z)
#endif

using namespace std;
using ll = long long;
using pii = pair<int, int>;

int n;
double l, wmax;

vector<double> base, x;

void solve() {
	int r = 0;
	int l = 0;
	ll ans = 0;

	for (double b : base) {
		while (l < x.size() && (x[l] < b || abs((x[l] + b) / (x[l] - b)) > wmax - 1e-8))
			l++;
		ans += x.size() - l;
//		dbg2(b, x[l]);
	}
	cout << ans << endl;
}

void load() {
	cin >> n >> l >> wmax;
	for (int i = 0; i < n; i++) {
		int xx, v;
		cin >> xx >> v;
		if (v > 0)
			base.push_back(xx);
		else
			x.push_back(xx + l);
	}
	sort(base.begin(), base.end());
	sort(x.begin(), x.end());
}

int main()
{
#ifndef LOCAL
	ios::sync_with_stdio(0);
	cin.tie(0);
#endif
	load();
	solve();
	return 0;
}


#include <bits/stdc++.h>

#define N (1<<17)
#define ll long long
#define ull unsigned long long
#define ld long double
#define M 1000000007
#define INF 0x5ADFACE5
#define LINF 0x51DEEFFEC7C0DECALL
#define pii pair<int, int>
#define pll pair<long long, long long>
#define F first
#define S second

using namespace std;

vector<ll> nn;
vector<ll> np;
vector<ll> pn;
vector<ll> pp;

int main () {
	ll n, l, wm;
	cin>>n>>l>>wm;
	for (int i = 0; i < n; i++) {
		ll x, w;
		cin>>x>>w;
		if (x + l <= 0 && w < 0) nn.push_back(-x - l); // <- |
		else if (w < 0) pn.push_back(x);          	   // | <-
		else if (x < 0) np.push_back(-x - l); 		   // -> |
		else pp.push_back(x);					 	   // | ->
	}
	ll ans = (ll)np.size() * (ll)pn.size();
	sort(nn.begin(), nn.end());
	sort(np.begin(), np.end());
	sort(pn.begin(), pn.end());
	sort(pp.begin(), pp.end());
	if (wm > 1) for (ll i = 0; i < pp.size(); i++) {
		ll k = -1;
		ll s0 = pp[i] * (wm + 1);
		ll s1 = (pp[i] + l) * (wm + 1);
		if (s0 > s1) swap(s0, s1);
		for (ll m = pn.size(); m >= 1; m /= 2) {
			while (k + m < pn.size()) {
				ll t0 = pn[k + m] * (wm - 1);
				ll t1 = (pn[k + m] + l) * (wm - 1);
				if (t0 > t1) swap(t0, t1);
				//cout<<(k + m)<<" -> "<<((ld)t0 / (wm * wm - 1))<<" "<<((ld)t1 / (wm * wm - 1))<<" "<<((ld)s0 / (wm * wm - 1))<<" "<<((ld)s1 / (wm * wm - 1))<<endl;
				if (s0 >= t1) k += m;
				else break;
			}
		}
		k++;
		ans += ((ll)pn.size() - (ll)k);
	}

	if (wm > 1) for (ll i = 0; i < nn.size(); i++) {
		ll k = -1;
		ll s0 = nn[i] * (wm + 1);
		ll s1 = (nn[i] + l) * (wm + 1);
		if (s0 > s1) swap(s0, s1);
		for (ll m = np.size(); m >= 1; m /= 2) {
			while (k + m < np.size()) {
				ll t0 = np[k + m] * (wm - 1);
				ll t1 = (np[k + m] + l) * (wm - 1);
				if (t0 > t1) swap(t0, t1);
				//cout<<(k + m)<<" -> "<<((ld)t0 / (wm * wm - 1))<<" "<<((ld)t1 / (wm * wm - 1))<<" "<<((ld)s0 / (wm * wm - 1))<<" "<<((ld)s1 / (wm * wm - 1))<<endl;
				if (s0 >= t1) k += m;
				else break;
			}
		}
		k++;
		ans += ((ll)np.size() - k);
	}

	cout<<ans<<endl;
}


#include <bits/stdc++.h>

#define N (1<<17)
#define ll long long
#define ull unsigned long long
#define ld long double
#define M 1000000007
#define INF 0x5ADFACE5
#define LINF 0x51DEEFFEC7C0DECALL
#define pii pair<int, int>
#define pll pair<long long, long long>
#define F first
#define S second

using namespace std;

vector<int> nn;
vector<int> np;
vector<int> pn;
vector<int> pp;

int main () {
	int n, l, wm;
	cin>>n>>l>>wm;
	for (int i = 0; i < n; i++) {
		int x, w;
		cin>>x>>w;
		if (x + l <= 0 && w < 0) nn.push_back(-x - l);// <- |
		else if (w < 0) pn.push_back(x);          // | <-
		else if (x < 0) np.push_back(-x - l); 		  // -> |
		else pp.push_back(x);					  // | ->
	}
	ll ans = (ll)np.size() * (ll)pn.size();
	sort(nn.begin(), nn.end());
	sort(np.begin(), np.end());
	sort(pn.begin(), pn.end());
	sort(pp.begin(), pp.end());
	if (wm > 1) for (int i = 0; i < pp.size(); i++) {
		int k = -1;
		ll s0 = pp[i] * (wm + 1);
		ll s1 = (pp[i] + l) * (wm + 1);
		if (s0 > s1) swap(s0, s1);
		for (int m = pn.size(); m >= 1; m /= 2) {
			while (k + m < pn.size()) {
				ll t0 = pn[k + m] * (wm - 1);
				ll t1 = (pn[k + m] + l) * (wm - 1);
				if (t0 > t1) swap(t0, t1);
				//cout<<(k + m)<<" -> "<<((ld)t0 / (wm * wm - 1))<<" "<<((ld)t1 / (wm * wm - 1))<<" "<<((ld)s0 / (wm * wm - 1))<<" "<<((ld)s1 / (wm * wm - 1))<<endl;
				if (s0 >= t1) k += m;
				else break;
			}
		}
		k++;
		ans += (pn.size() - k);
	}

	if (wm > 1) for (int i = 0; i < nn.size(); i++) {
		int k = -1;
		ll s0 = nn[i] * (wm + 1);
		ll s1 = (nn[i] + l) * (wm + 1);
		if (s0 > s1) swap(s0, s1);
		for (int m = np.size(); m >= 1; m /= 2) {
			while (k + m < np.size()) {
				ll t0 = np[k + m] * (wm - 1);
				ll t1 = (np[k + m] + l) * (wm - 1);
				if (t0 > t1) swap(t0, t1);
				//cout<<(k + m)<<" -> "<<((ld)t0 / (wm * wm - 1))<<" "<<((ld)t1 / (wm * wm - 1))<<" "<<((ld)s0 / (wm * wm - 1))<<" "<<((ld)s1 / (wm * wm - 1))<<endl;
				if (s0 >= t1) k += m;
				else break;
			}
		}
		k++;
		ans += (np.size() - k);
	}

	cout<<ans<<endl;
}


#include <bits/stdc++.h>

#define N (1<<17)
#define ll long long
#define ull unsigned long long
#define ld long double
#define M 1000000007
#define INF 0x5ADFACE5
#define LINF 0x51DEEFFEC7C0DECALL
#define pii pair<int, int>
#define pll pair<long long, long long>
#define F first
#define S second

using namespace std;

vector<int> nn;
vector<int> np;
vector<int> pn;
vector<int> pp;

int main () {
	int n, l, wm;
	cin>>n>>l>>wm;
	for (int i = 0; i < n; i++) {
		int x, w;
		cin>>x>>w;
		if (x + l <= 0 && w < 0) nn.push_back(-x); // <- |
		else if (w < 0) pn.push_back(x);          // | <-
		else if (x < 0) np.push_back(-x); 		  // -> |
		else pp.push_back(x);					  // | ->
	}
	ll ans = (ll)np.size() * (ll)pn.size();
	sort(nn.begin(), nn.end());
	sort(np.begin(), np.end());
	sort(pn.begin(), pn.end());
	sort(pp.begin(), pp.end());
	if (wm > 1) for (int i = 0; i < pp.size(); i++) {
		int k = -1;
		ll s0 = pp[i] * (wm + 1);
		ll s1 = (pp[i] + l) * (wm + 1);
		if (s0 > s1) swap(s0, s1);
		for (int m = pn.size(); m >= 1; m /= 2) {
			while (k + m < pn.size()) {
				ll t0 = pn[k + m] * (wm - 1);
				ll t1 = (pn[k + m] + l) * (wm - 1);
				if (t0 > t1) swap(t0, t1);
				//cout<<(k + m)<<" -> "<<((ld)t0 / (wm * wm - 1))<<" "<<((ld)t1 / (wm * wm - 1))<<" "<<((ld)s0 / (wm * wm - 1))<<" "<<((ld)s1 / (wm * wm - 1))<<endl;
				if (s0 >= t1) k += m;
				else break;
			}
		}
		k++;
		//cout<<pp[i]<<" "<<k<<endl;
		ans += (pn.size() - k);
	}

	if (wm > 1) for (int i = 0; i < nn.size(); i++) {
		int k = -1;
		ll s0 = nn[i] * (wm + 1);
		ll s1 = (nn[i] + l) * (wm + 1);
		if (s0 > s1) swap(s0, s1);
		for (int m = np.size(); m >= 1; m /= 2) {
			while (k + m < np.size()) {
				ll t0 = np[k + m] * (wm - 1);
				ll t1 = (np[k + m] + l) * (wm - 1);
				if (t0 > t1) swap(t0, t1);
				//cout<<(k + m)<<" -> "<<((ld)t0 / (wm * wm - 1))<<" "<<((ld)t1 / (wm * wm - 1))<<" "<<((ld)s0 / (wm * wm - 1))<<" "<<((ld)s1 / (wm * wm - 1))<<endl;
				if (s0 >= t1) k += m;
				else break;
			}
		}
		k++;
		//cout<<pp[i]<<" "<<k<<endl;
		ans += (np.size() - k);
	}

	cout<<ans<<endl;
}


#include<bits/stdc++.h>

using namespace std;

#define allof(x) (x).begin(), (x).end()

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

ll N, L, W;

vector<ll> pos;

deque<ll> dq;

bool goodp(ll l, ll r){
    ll x = (l + r) / 2;
    ll y = x - l;
    return abs(x) < y * W;
}

bool good(ll l, ll r){
    return goodp(l, r) || goodp(l + L, r) || goodp(l, r + L) || goodp(l + L, r + L);
}

int main(){
    cin.tie(0);
    cin.sync_with_stdio(0);

    cin >> N >> L >> W;

    L *= 2;

    while(N--){
        ll x, v;
        cin >> x >> v;

        x *= 2;

        if(v == 1){
            pos.push_back(x);
        } else {
            dq.push_back(x);
        }
    }

    sort(allof(pos));
    sort(allof(dq));

    ll ans = 0;

    for(ll i : pos){
        while(!dq.empty() && !good(i, dq.front())){
            dq.pop_front();
        }
        while(!dq.empty() && !good(i, dq.back())){
            dq.pop_back();
        }
        ans += dq.size();
    }

    cout << ans;
}


#include<bits/stdc++.h>

using namespace std;

#define allof(x) (x).begin(), (x).end()

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

ll N, L, W;

vector<ll> pos;

deque<ll> dq;

int main(){
    cin.tie(0);
    cin.sync_with_stdio(0);

    cin >> N >> L >> W;

    L *= 2;

    while(N--){
        ll x, v;
        cin >> x >> v;

        x *= 2;

        if(v == 1){
            pos.push_back(x);
        } else {
            dq.push_back(x);
        }
    }

    sort(allof(pos));
    sort(allof(dq));

    int l = 0, r = dq.size() - 1;

    ll ans = 0;

    for(ll i : pos){

        while(l <= r){
            ll X1 = (i + dq[l]) / 2;
            ll X2 = (i + dq[l]) / 2 + L;
            ll Y = X1 - i;

            if(-W * Y < X2 && X1 < W * Y){
                break;
            } else {
                l++;
            }
        }

        while(l <= r){
            ll X1 = (i + dq[r]) / 2;
            ll X2 = (i + dq[r]) / 2 + L;
            ll Y = X1 - i;

            if(-W * Y < X2 && X1 < W * Y){
                break;
            } else {
                l++;
            }
        }

        ans += r - l + 1;
    }

    cout << ans;
}


#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define ld long double
#define mod 1000000007LL
#define eps 1e-13
#define PI 3.141592653589793238L
#define INF 1000000011
#define INFLL 1000000000000000011LL
#define endl '\n'
#define vi vector<int>
#define vs vector<string>
#define vll vector<long long>
#define vc vector<char>
#define vs vector<string>
#define pii pair<int, int>
#define pll pair<long long, long long>
#define pil pair<int, long long>
#define pli pair<long long, int>
#define pcc pair<char, char>
#define pdd pair<double, double>
#define mp make_pair
#define F first
#define S second
#define pb(x) push_back(x)
#define fo(i,a,n) for(i = (a); i < (n); i++)
#define foi(i,a,n) for(i = (a); i <= (n); i++)
#define pd(x) cout<<x
#define sd(x) cin>>x
#define nl cout<<endl
#define gtl(x) getline(cin, (x))
#define flsh fflush(stdout)
#define sws ios_base::sync_with_stdio(false); cin.tie(0)
#define gcd __gcd
#define clr(x) memset(x,0,sizeof(x))
#define all(a) (a).begin(), (a).end()
#define foreach(i,a) for(__typeof((a).begin()) i = (a).begin(); i != (a).end(); ++i)
#define sz(a) (int)((a).size())
//int a[25]= { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 };
//int dw[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
//int dw[8][2]={{0,1},{1,0},{0,-1},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1}};
//ll fibonacci[2][2] = {{0,1},{1,1}};
//ll identity[2][2] = {{1,0},{0,1}};
ll i,j,k;

inline ll div_floor(ll a, ll b) {
    if (b == 0) return (a > 0 ? INFLL : -INFLL);
    if (a % b < 0) a -= (b + a % b);
    return a / b;
}

int main() {
	ll n,l,w;
	cin>>n>>l>>w;
	vll pos, neg;
	fo(i,0,n) {
		ll a,b;
		cin>>a>>b;
		if(b == -1) neg.pb(a);
		else pos.pb(a);
	}
	sort(all(pos));
	sort(all(neg));

	ll ans = 0;
	for(ll v : neg) {
		auto barrier = lower_bound(all(pos), -v - l);
		ll u1 = div_floor((ll)(v+l)*(w+1) - 1,w-1);
		ll u2 = div_floor((ll)(v+l)*(w-1) - 1,w+1);
		ans += (upper_bound(pos.begin(), barrier, u1) - pos.begin()) + (upper_bound(barrier, pos.end(), min(v, u2)) - barrier);
	}
	cout<<ans<<endl;

	return 0;
}


//litianfeng
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
#include <utility>
#include <bitset>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstdio>
#include <cstring>
#include <climits>
#include <string.h>
#include <stdio.h>
#define LL long long
#define pii pair<int,int>
#define piii pair<int, pii >
#define REP(i,n) for (int (i)=0;(i)<(n);(i)++)
#define vi vector<int>
#define vpi vector< pii >
#define INF 2147483647
#define big 20160116
#define pb push_back
#define mp make_pair
using namespace std;

int n,l,w;
int x[100050],y[100050];
int mydiv(long long a,int b)
{
    if (b==0) if (a>0)return INF;
    else return -INF;
    if (a%b<0) a-=(b+a%b);
    return a/b;
}
int main()
{
    cin>>n>>l>>w;
    int m=0,q=0;
    for (int i=0;i<n;i++)
    {
        int k,t;
        scanf("%d%d",&t,&k);
        if (k==1) x[m++]=t;
        else y[q++]=t;
    }
    sort(x,x+m);
    sort(y,y+q);
    long long ans = 0;
 //   int ans = 0;
    for (int i=0;i<q;i++)
    {
        int t=lower_bound(x,x+m,-y[i]-l) - x;
        int p1=mydiv((long long)(y[i]+l)*(w+1)-1,w-1);
        int p2=mydiv((long long)(y[i]+l)*(w-1)-1,w+1);

     //   printf("before %d cloud: %d\n",i,ans);
       // ans+= i-(upper_bound(x,x+m,x[i]-l)-x);
       ans+=upper_bound(x,x+t,p1)-x;
       ans+=upper_bound(x+t,x+m,min(y[i],p2))-(x+t);
       // ans+= (upper_bound(x,x+m,x[i]+l)-x) - (lower_bound(x,x+m,x[i])-x);
       // printf("after %d cloud: %d\n",i,ans);
    }

    cout<<ans<<endl;
    return 0;
}


//litianfeng
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
#include <utility>
#include <bitset>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstdio>
#include <cstring>
#include <climits>
#include <string.h>
#include <stdio.h>
#define LL long long
#define pii pair<int,int>
#define piii pair<int, pii >
#define REP(i,n) for (int (i)=0;(i)<(n);(i)++)
#define vi vector<int>
#define vpi vector< pii >
#define INF 2147483647
#define big 20160116
#define pb push_back
#define mp make_pair
using namespace std;

int n,l,w;
int x[100050],y[100050];
int mydiv(long long a,int b)
{
    if (b==0) return INF;
    return a/b;
}
int main()
{
    cin>>n>>l>>w;
    int m=0,q=0;
    for (int i=0;i<n;i++)
    {
        int k,t;
        scanf("%d%d",&t,&k);
        if (k==1) x[m++]=t;
        else y[q++]=t;
    }
    sort(x,x+m);
    sort(y,y+q);
    long long ans = 0;
 //   int ans = 0;
    for (int i=0;i<q;i++)
    {
        int t=lower_bound(x,x+m,-y[i]-l) - x;
        int p1=mydiv((long long)(y[i]+l)*(w+1)-1,w-1);
        int p2=mydiv((long long)(y[i]+l)*(w-1)-1,w+1);

     //   printf("before %d cloud: %d\n",i,ans);
       // ans+= i-(upper_bound(x,x+m,x[i]-l)-x);
       ans+=upper_bound(x,x+t,p1)-x;
       ans+=upper_bound(x+t,x+m,min(y[i],p2))-x;
       // ans+= (upper_bound(x,x+m,x[i]+l)-x) - (lower_bound(x,x+m,x[i])-x);
       // printf("after %d cloud: %d\n",i,ans);
    }

    cout<<ans<<endl;
    return 0;
}


#pragma GCC optimize ("O3", "unroll-loops")
//#pragma GCC target ("avx2")
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include "bits/stdc++.h"
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define distinct(x) sort(all(x)); x.resize(unique(all(x))-x.begin())
#define pb push_back
#define mp make_pair
#define F first
#define S second
#define CASE(x) int x; cin >> x; while (x--)
#define CASEt(x) int x; cin >> x; for (int tc = 1; tc <= x; ++tc)
using namespace std;
using namespace __gnu_pbds;
namespace {
	const int MOD107 = 1000000007;
	const int MOD998 = 998244353;
	using ll = long long;
	using ull = unsigned long long;
	using pii = pair<int, int>;
	using pll = pair<ll, ll>;
	template <class T> using ordered_set = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;
	template <class T> using minheap = priority_queue<T, vector<T>, greater<T>>;
	template <class T> using maxheap = priority_queue<T, vector<T>, less<T>>;
	mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
//	mt19937_64 rng64(chrono::steady_clock::now().time_since_epoch().count());
	template <int MODVALUE>
	struct Modular {
	private:
		long long val;

	public:
		explicit operator long long() const { return val; }

		bool operator == (const Modular& other) { return val == other.val; }
		bool operator != (const Modular& other) { return val != other.val; }
		template<class T> bool operator == (const T& other) { return *this == Modular(other); }
		template<class T> bool operator != (const T& other) { return *this != Modular(other); }
		template<class T> friend bool operator == (const T& other, const Modular& m) { return Modular(other) == m; }
		template<class T> friend bool operator != (const T& other, const Modular& m) { return Modular(other) != m; }

		bool operator <  (const Modular& other) { return val <  other.val; }
		bool operator <= (const Modular& other) { return val <= other.val; }
		bool operator >  (const Modular& other) { return val >  other.val; }
		bool operator >= (const Modular& other) { return val >= other.val; }
		template<class T> bool operator <  (const T& other) { return *this <  Modular(other); }
		template<class T> bool operator <= (const T& other) { return *this <= Modular(other); }
		template<class T> bool operator >  (const T& other) { return *this >  Modular(other); }
		template<class T> bool operator >= (const T& other) { return *this >= Modular(other); }
		template<class T> friend bool operator <  (const T& other, const Modular& m) { return Modular(other) <  m; }
		template<class T> friend bool operator <= (const T& other, const Modular& m) { return Modular(other) <= m; }
		template<class T> friend bool operator >  (const T& other, const Modular& m) { return Modular(other) >  m; }
		template<class T> friend bool operator >= (const T& other, const Modular& m) { return Modular(other) >= m; }

		Modular& operator += (const Modular& other) { val += other.val; val %= MODVALUE; return *this; }
		Modular  operator +  (const Modular& other) { Modular tmp = *this; return tmp += other; }
		template<class T> Modular& operator += (const T& other) { return *this += Modular(other); }
		template<class T> Modular  operator +  (const T& other) { return *this +  Modular(other); }
		template<class T> friend Modular operator += (const T& other, const Modular& m) { return Modular(other) += m; }
		template<class T> friend Modular operator +  (const T& other, const Modular& m) { return Modular(other) +  m; }

		Modular& operator ++()    { return *this += 1; }
		Modular  operator ++(int) { Modular tmp = *this; ++*this; return tmp; }

		Modular  operator -  () const { return Modular(-val); }
		Modular& operator -= (const Modular& other) { val -= other.val; val += MODVALUE; val %= MODVALUE; return *this;}
		Modular  operator -  (const Modular& other) { Modular tmp = *this; return tmp -= other; }
		template<class T> Modular& operator -= (const T& other) { return *this -= Modular(other); }
		template<class T> Modular  operator -  (const T& other) { return *this -  Modular(other); }
		template<class T> friend Modular operator -= (const T& other, const Modular& m) { return Modular(other) -= m; }
		template<class T> friend Modular operator -  (const T& other, const Modular& m) { return Modular(other) -  m; }

		Modular& operator --()    { return *this -= 1; }
		Modular  operator --(int) { Modular tmp = *this; --*this; return tmp; }

		Modular& operator *= (const Modular& other) { val *= other.val; val %= MODVALUE; val += MODVALUE; val %= MODVALUE; return *this; }
		Modular  operator *  (const Modular& other) { Modular tmp = *this; return tmp *= other; }
		template<class T> Modular& operator *= (const T& other) { return *this *= Modular(other); }
		template<class T> Modular  operator *  (const T& other) { return *this *  Modular(other); }
		template<class T> friend Modular operator *= (const T& other, const Modular& m) { return Modular(other) *= m; }
		template<class T> friend Modular operator *  (const T& other, const Modular& m) { return Modular(other) *  m; }

		Modular pow(long long power) const {
			Modular m = *this, ans = 1;
			while (power) {
				if (power & 1) ans *= m;
				m *= m;
				power >>= 1;
			}
			return ans;
		}
		Modular pow(const Modular& other) const { return pow(other.val); }
		Modular inv() const { return pow(MODVALUE-2); }

		Modular& operator /= (const Modular& other) { val *= other.inv().val; val %= MODVALUE; return *this; }
		Modular  operator /  (const Modular& other) { Modular tmp = *this; return tmp /= other; }
		template<class T> Modular& operator /= (const T& other) { return *this /= Modular(other); }
		template<class T> Modular  operator /  (const T& other) { return *this /  Modular(other); }
		template<class T> friend Modular operator /= (const T& other, const Modular& m) { return Modular(other) /= m; }
		template<class T> friend Modular operator /  (const T& other, const Modular& m) { return Modular(other) /  m; }

		friend istream& operator >> (istream& in, Modular& m) { in >> m.val; m.val %= MODVALUE; m.val += MODVALUE; m.val %= MODVALUE; return in; }
		friend ostream& operator << (ostream& out, const Modular& m) { return out << m.val; }

		Modular() : val(0) {}
		Modular(int val) : val((val % MODVALUE + MODVALUE) % MODVALUE) {};
		Modular(long long val) : val((val % MODVALUE + MODVALUE) % MODVALUE) {};
	};
	inline ll pow(ll b, ll p, ll mod) {
		b %= mod;
		ll ans = 1;
		for (; p > 0; p >>= 1) {
			if (p&1) {ans *= b; ans %= mod;}
			b *= b;
			b %= mod;
		}
		return ans;
	}
	inline ll max(ll a, int b) { return (a > b ? a : b); }
	inline ll max(int a, ll b) { return (a > b ? a : b); }
	inline ll min(ll a, int b) { return (a < b ? a : b); }
	inline ll min(int a, ll b) { return (a < b ? a : b); }
	template <class T> inline bool chkmin(T&x, const T& y) { return x > y ? x = y, 1 : 0; }
	template <class T> inline bool chkmax(T&x, const T& y) { return x < y ? x = y, 1 : 0; }
}
namespace IO {
	template<class T> inline void _R(T &x) {cin >> x;}
	template<class T1, class T2> inline void _R(pair<T1,T2> &x) {_R(x.first); _R(x.second);}
	template<class T> inline void _R(vector<T> &x) {for (auto& i : x) _R(i);}
	template<class T> inline void _R(deque<T> &x) {for (auto& i : x) _R(i);}
	inline void R() {}
	template<class T1, class... T2> inline void R(T1 &x, T2 &...y) { _R(x); R(y...);}

	template<class T> inline void _W(const T& x);
	template<class T1, class T2> inline void _W(const pair<T1,T2>& p);
	template<class... T> inline void _W(const vector<T...>& x);
	template<class... T> inline void _W(const deque<T...>& x);
	template<class... T> inline void _W(const forward_list<T...>& x);
	template<class... T> inline void _W(const list<T...>& x);
	template<class... T> inline void _W(const set<T...>& x);
	template<class... T> inline void _W(const multiset<T...>& x);
	template<class... T> inline void _W(const unordered_set<T...>& x);
	template<class... T> inline void _W(const unordered_multiset<T...>& x);
	template<class... T> inline void _W(const map<T...>& x);
	template<class... T> inline void _W(const multimap<T...>& x);
	template<class... T> inline void _W(const unordered_map<T...>& x);
	template<class... T> inline void _W(const unordered_multimap<T...>& x);

	template<class T> inline void _W(const ordered_set<T>& x);

	template<class Container> inline void printContainer(const Container& x) { bool isFirst = 1; for (auto i : x) { if (!isFirst) cout << ' '; isFirst = 0; _W(i); } }

	template<class T> inline void _W(const T& x) {cout << x;}
	template<class T1, class T2> inline void _W(const pair<T1,T2>& p) {_W(p.first); _W(' '); _W(p.second);}
	template<class... T> inline void _W(const vector<T...>& x) { printContainer(x); }
	template<class... T> inline void _W(const deque<T...>& x) { printContainer(x); }
	template<class... T> inline void _W(const forward_list<T...>& x) { printContainer(x); }
	template<class... T> inline void _W(const list<T...>& x) { printContainer(x); }
	template<class... T> inline void _W(const set<T...>& x) { printContainer(x); }
	template<class... T> inline void _W(const multiset<T...>& x) { printContainer(x); }
	template<class... T> inline void _W(const unordered_set<T...>& x) { printContainer(x); }
	template<class... T> inline void _W(const unordered_multiset<T...>& x) { printContainer(x); }
	template<class... T> inline void _W(const map<T...>& x) { printContainer(x); }
	template<class... T> inline void _W(const multimap<T...>& x) { printContainer(x); }
	template<class... T> inline void _W(const unordered_map<T...>& x) { printContainer(x); }
	template<class... T> inline void _W(const unordered_multimap<T...>& x) { printContainer(x); }

	template<class T> inline void _W(const ordered_set<T>& x) { printContainer(x); }

 	inline void W() {cout << '\n';}
	template<class T> inline void W(const T &x) {_W(x); W();}
	template<class T1, class... T2> inline void W(const T1 &x, const T2 &...y) { _W(x); _W(' '); W(y...);}
} using namespace IO;
namespace outputFormat{
	inline string Case(int tc) {return "Case #" + to_string(tc) + ':';}
	inline string YN(bool b) {return b ? "Yes" : "No";}
} using namespace outputFormat;
namespace std {
    template <class T1, class T2> struct hash<pair<T1,T2>> {
    	std::size_t operator()(pair<T1,T2> _) const {
        	return hash<T1>{}(_.first) ^ hash<T2>{}(_.second);
    	}
    };
}
using Mint = Modular<MOD107>;

ll l,w;
bool check(ll rv, ll lv) {
	rv += l;
	ll d = lv - rv;

	if (d < 0)
		return 0;

	ll p2 = abs(lv + rv);

	if (d * w > p2)
		return 1;

	ll pl2 = p2 - l;
	ll pr2 = p2 + l;

	if (pl2 <= 0 && 0 <= pr2)
		return 1;

	ll minp = min(abs(pl2), abs(pr2));
	if ((d + l) * w > minp)
		return 1;

	if ((d + l * 2) * w > p2)
		return 1;

	return 0;
}

int main() {
	ll n; R(n,l,w);
	vector<ll> cl, cr;

	for (int i = 0; i < n; i++) {
		ll x; int v; R(x, v);
		if (v == -1)
			cl.pb(x);
		else
			cr.pb(x);
	}

	sort(all(cl));
	sort(all(cr));

	if (cl.empty() || cr.empty()) {
		W(0);
		return 0;
	}

	ll ans = 0;
	const int MAXI = 131072;
	for (auto& i : cr) {
		int p = cl.size();
		if (i <= -l)
			p = lower_bound(all(cl), -(i + l)) - cl.begin();

		int l = p, r = p - 1;
		for (int inc = MAXI; inc >= 1; inc >>= 1) {
			if (r + inc < cl.size() && check(i, cl[r + inc]))
				r += inc;
		}

		for (int dec = MAXI; dec >= 1; dec >>= 1) {
			if (l - dec >= 0 && check(i, cl[l - dec]))
				l -= dec;
		}

		ans += (r - (p - 1));
		ans += (p - l);
	}

	W(ans);

 	return 0;
}

static auto _batch_ios = [](){
#ifndef LOCAL
	ios::sync_with_stdio(false);
	cin.tie(0);
#endif
	cout << fixed << setprecision(10);
	return 42;
}();


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;

const int maxn = 150100;
char sym[maxn];
int h[maxn];
int deg[maxn];
vector<int> g[maxn];
array<int, 26> a[maxn][2];
pair<int, int> up[maxn];
int pr[maxn];
int leaves_h = -1;
int q;
int bad_deg = 0;

void sosat() {
  //cerr << "sosat\n";
  for (int i = 0; i < q; ++i) {
    cout << "Fou\n";
  }
  exit(0);
}

vector<int> pre(int u) {
  assert((int) g[u].size() <= 2);
  if (g[u].empty()) {
    if (leaves_h == -1) {
      leaves_h = h[u];
    } else if (leaves_h != h[u]) {
      sosat();
    }
  }
  vector<int> res(26);
  for (int i = 0; i < (int) g[u].size(); ++i) {
    int v = g[u][i];
    h[v] = h[u] + 1;
    if ((int) g[u].size() == 2) {
      up[v] = {u, i};
    } else {
      up[v] = up[u];
    }
    auto arr = pre(v);
    if (sym[v] != '?') {
      arr[sym[v] - 'a']++;
    }
    for (int j = 0; j < 26; ++j) {
      a[u][i][j] = arr[j];
    }
    for (int j = 0; j < 26; ++j) {
      res[j] = max(res[j], arr[j]);
    }
  }
  if (g[u].size() == 2 || u == 0) {
    deg[u] = leaves_h - h[u] - accumulate(res.begin(), res.end(), 0);
    if (deg[u] < 0) {
      ++bad_deg;
    }
  }
  return res;
}

void update_arr(int u, int i, char sym, int delta) {
  if (sym == '?') {
    return;
  }
  int c = sym - 'a';
  bad_deg -= deg[u] < 0;
  deg[u] += max(a[u][i][c], a[u][i ^ 1][c]);
  a[u][i][c] += delta;
  deg[u] -= max(a[u][i][c], a[u][i ^ 1][c]);
  bad_deg += deg[u] < 0;
}

void do_replace(int u, char from, char to) {
  while (u > 0) {
    int id;
    tie(u, id) = up[u];
    update_arr(u, id, from, -1);
    update_arr(u, id, to, +1);
  }
}

signed main() {
#ifdef LOCAL
  assert(freopen("d.in", "r", stdin));
#endif
  ios::sync_with_stdio(false);
  cin.tie(0);

  int n;
  cin >> n >> q;
  for (int i = 1; i < n; ++i) {
    int p;
    char c;
    cin >> p >> c;
    --p;
    pr[i] = p;
    g[p].push_back(i);
    sym[i] = c;
  }
  pre(0);
  for (int i = 0; i < q; ++i) {
    int u;
    char c;
    cin >> u >> c;
    --u;
    do_replace(u, sym[u], c);
    sym[u] = c;
    if (bad_deg > 0) {
      cout << "Fou\n";
    } else {
      int res = 0;
      for (int c = 0; c < 26; ++c) {
        res += (c + 1) * (max(a[0][0][c], a[0][1][c]) + deg[0]);
      }
      cout << "Shi " << res << '\n';
    }
  }
}


#include <bits/stdc++.h>
using namespace std;

using uint=unsigned;
using ll=long long;
using ull=unsigned long long;
#define int ll

#define FOR(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,b) FOR(i,0,b)
#define ROF(i,a,b) for(int i=int(b)-1;i>=a;i--)
#define per(i,b) ROF(i,0,b)
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define eb emplace_back
#define all(x) x.begin(),x.end()
auto& errStream=cerr;
#ifdef LOCAL
#define cerr (cerr<<"-- line "<<__LINE__<<" -- ")
#else
class CerrDummy{}cerrDummy;
template<class T>
CerrDummy& operator<<(CerrDummy&cd,const T&){
	return cd;
}
using charTDummy=char;
using traitsDummy=char_traits<charTDummy>;
CerrDummy& operator<<(CerrDummy&cd,basic_ostream<charTDummy,traitsDummy>&(basic_ostream<charTDummy,traitsDummy>&)){
	return cd;
}
#define cerr cerrDummy
#endif
#define reach cerr<<"reached"<<endl
void dmpr(decltype(cerr)&os){os<<endl;}
template<class T,class... Args>
void dmpr(decltype(cerr)&os,const T&t,const Args&... args){
	os<<t<<" ";
	dmpr(os,args...);
}
#define dmp(...) dmpr(cerr,##__VA_ARGS__)
#define zero(x) memset(x,0,sizeof(x))
#define one(x) memset(x,-1,sizeof(x))
#define fs first
#define sc second
#define bg begin()
#define ed end()

template<class T> using V=vector<T>;
template<class T> using VV=V<V<T>>;

using pi=pair<int,int>;
using vi=vector<int>;
using ld=long double;

template<class T,class U>
ostream& operator<<(ostream& os,const pair<T,U>& p){
	os<<"("<<p.first<<","<<p.second<<")";
	return os;
}

template<class T>
ostream& operator <<(ostream& os,const vector<T>& v){
	os<<"{";
	rep(i,(int)v.size()){
		if(i)os<<",";
		os<<v[i];
	}
	os<<"}";
	return os;
}

template<int i,class T>
void print_tuple(ostream&,const T&){
}

template<int i,class T,class H,class ...Args>
void print_tuple(ostream&os,const T&t){
	if(i)os<<",";
	os<<get<i>(t);
	print_tuple<i+1,T,Args...>(os,t);
}

template<class ...Args>
ostream& operator<<(ostream&os,const tuple<Args...>&t){
	os<<"(";
	print_tuple<0,tuple<Args...>,Args...>(os,t);
	return os<<")";
}

ll read(){
	ll i;
	scanf("%lld",&i);
	return i;
}

void printSpace(){
	printf(" ");
}

void printEoln(){
	printf("\n");
}

void print(ll x,int suc=1){
	printf("%lld",x);
	if(suc==1)
		printEoln();
	if(suc==2)
		printSpace();
}

vi readvi(int n,int off=0){
	vi v(n);
	rep(i,n)v[i]=read()+off;
	return v;
}

template<class T>
void print(const vector<T>&v,int suc=1){
	rep(i,v.size())
		print(v[i],i==int(v.size())-1?suc:2);
}

string readString(){
	static char buf[3341000];
	scanf("%s",buf);
	return string(buf);
}

char* readCharArray(){
	static char buf[3341000];
	static int bufUsed=0;
	char* ret=buf+bufUsed;
	scanf("%s",ret);
	bufUsed+=strlen(ret)+1;
	return ret;
}

template<class T,class U>
void chmax(T& a,U b){
	if(a<b)
		a=b;
}

template<class T,class U>
void chmin(T& a,U b){
	if(b<a)
		a=b;
}

template<class T>
T Sq(const T& t){
	return t*t;
}

//#define CAPITAL
void Yes(bool ex=true){
	#ifdef CAPITAL
	cout<<"YES"<<endl;
	#else
	cout<<"Yes"<<endl;
	#endif
	if(ex)exit(0);
}
void No(bool ex=true){
	#ifdef CAPITAL
	cout<<"NO"<<endl;
	#else
	cout<<"No"<<endl;
	#endif
	if(ex)exit(0);
}

const ll infLL=LLONG_MAX/3;

#ifdef int
const int inf=infLL;
#else
const int inf=INT_MAX/2-100;
#endif

constexpr ll TEN(int n){
	return n==0?1:TEN(n-1)*10;
}

template<class T>
vector<T> uni(const vector<T>&vv){
	auto v(vv);
	sort(all(v));
	v.erase(unique(all(v)),v.end());
	return v;
}
template<class T>
void mkuni(vector<T>&v){
	sort(all(v));
	v.erase(unique(all(v)),v.end());
}

//ayasii
int topbit(signed t){
	return t==0?-1:31-__builtin_clz(t);
}
int topbit(ll t){
	return t==0?-1:63-__builtin_clzll(t);
}
int popcount(signed t){
	return __builtin_popcount(t);
}
int popcount(ll t){
	return __builtin_popcountll(t);
}
bool ispow2(int i){
	return i&&(i&-i)==i;
}

bool inc(int a,int b,int c){
	return a<=b&&b<=c;
}

void AllNo(int q){
	rep(_,q)
		printf("Fou\n");
	exit(0);
}

//without rank
struct UnionFind{
	vi par,sz;
	UnionFind(int n){
		par.resize(n,-1);
		sz.resize(n,1);
	}
	int Find(int a){
		return par[a]==-1?a:(par[a]=Find(par[a]));
	}
	void Unite(int a,int b){
		a=Find(a);
		b=Find(b);
		if(a==b)return;
		assert(par[a]==-1);
		assert(par[b]==-1);
		par[b]=a;
		sz[a]+=sz[b];
	}
	int Size(int a){
		return sz[Find(a)];
	}
};

const int Nmax=150010;
int cnt[Nmax][26],ups[Nmax][26],sum[Nmax];
bool brk[Nmax];
int ch[Nmax][2];

signed main(){
	int n=read(),q=read();
	vi p(n,-1);
	V<char> cs(n);
	FOR(i,1,n){
		p[i]=read()-1;
		cs[i]=readString()[0];
		if(cs[i]!='?')
			ups[i][cs[i]-'a']++;
	}
	vi len(n,0);
	ROF(i,1,n){
		if(len[p[i]]&&len[p[i]]!=len[i]+1)
			AllNo(q);
		len[p[i]]=len[i]+1;
	}
	UnionFind uf(n);
	V<bool> al(n);
	{
		vi inc(n);
		FOR(i,1,n)
			inc[p[i]]++;
		inc[0]=2;
		FOR(i,1,n)if(inc[i]!=1){
			int x=p[i];
			while(inc[x]==1){
				uf.Unite(i,x);
				rep(k,26)
					ups[i][k]+=ups[x][k];
				x=p[x];
			}
			p[i]=x;
		}
		rep(i,n)
			al[i]=inc[i]!=1;
	}
	one(ch);
	FOR(i,1,n)if(al[i]){
		if(ch[p[i]][0]==-1)
			ch[p[i]][0]=i;
		else
			ch[p[i]][1]=i;
	}
	per(i,n)if(al[i]&&ch[i][0]!=-1){
		rep(c,2)if(ch[i][c]!=-1){
			rep(k,26)
				chmax(cnt[i][k],cnt[ch[i][c]][k]+ups[ch[i][c]][k]);
			brk[i]|=brk[ch[i][c]];
		}
		sum[i]=accumulate(cnt[i],cnt[i]+26,0);
		brk[i]|=sum[i]>len[i];
	}
	rep(_,q){
		int v=read()-1,x=uf.Find(v);
		char d=readString()[0];
		int pos[2]{-1,-1};
		if(d!=cs[v]){
			if(d!='?'){
				pos[0]=d-'a';
				ups[x][d-'a']++;
			}
			if(cs[v]!='?'){
				pos[1]=cs[v]-'a';
				ups[x][cs[v]-'a']--;
			}
			cs[v]=d;
			while(1){
				x=p[x];
				if(x==-1)break;
				brk[x]=false;
				rep(c,2)if(ch[x][c]!=-1)
					brk[x]|=brk[ch[x][c]];
				rep(k,2)if(pos[k]!=-1){
					sum[x]-=cnt[x][pos[k]];
					cnt[x][pos[k]]=0;
					rep(c,2)if(ch[x][c]!=-1)
						chmax(cnt[x][pos[k]],cnt[ch[x][c]][pos[k]]+ups[ch[x][c]][pos[k]]);
					sum[x]+=cnt[x][pos[k]];
				}
				brk[x]|=sum[x]>len[x];
			}
		}
		if(brk[0])
			printf("Fou\n");
		else{
			printf("Shi ");
			int f=len[0]-sum[0];
			int ans=0;
			rep(i,26)
				ans+=(i+1)*(cnt[0][i]+f);
			print(ans);
		}
	}
}


#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); --i)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int FFTMOD = 119 << 23 | 1;
const int INF = (int) 1e9 + 23111992;
const ll LINF = (ll) 1e18 + 23111992;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
inline ull isqrt(ull k) {ull r = sqrt(k) + 1; while (r * r > k) r--; return r;}
inline ll icbrt(ll k) {ll r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}
mt19937 mt(chrono::high_resolution_clock::now().time_since_epoch().count());
inline int mrand() {return abs((int) mt());}
#define db(x) cerr << "[" << #x << ": " << (x) << "] ";
#define endln cerr << "\n";

struct node_t {
    vi vals;
    int z, total;
    node_t() {
        vals.resize(26);
        z = -1;
    }
};

node_t join(node_t a, node_t b) {
    if (a.z == -1 || b.z == -1) return node_t();
    node_t c;
    int total = 0;
    FOR(i, 0, 26) {
        c.vals[i] = max(a.vals[i], b.vals[i]);
        if (a.vals[i] < b.vals[i]) {
            total += b.vals[i] - a.vals[i];
        }
    }
    if (a.z < total) {
        return node_t();
    }
    c.z = a.z - total;
    c.total = total;
    return c;
}

node_t add(node_t a, char c) {
    if (a.z == -1) return a;
    if (c == '?') {
        a.z++;
    }
    else {
        a.vals[c - 'a']++;
    }
    return a;
}

node_t rem(node_t a, char c) {
    if (a.z == -1) return a;
    if (c == '?') {
        a.z--;
    }
    else {
        a.vals[c - 'a']--;
    }
    return a;
}

void solve() {
    int n, q; cin >> n >> q;
    vector<vi> adj(n);
    vi par(n);
    vector<char> c(n);
    FOR(i, 1, n) {
        cin >> par[i] >> c[i]; par[i]--;
        adj[par[i]].pb(i);
    }
    vi lev(n);
    vi nxt(n);
    function<void(int)> dfs = [&] (int u) {
        nxt[u] = u;
        for (int v : adj[u]) {
            lev[v] = lev[u] + 1;
            if (sz(adj[u]) == 1) {
                nxt[v] = nxt[u];
            }
            dfs(v);
        }
    };
    dfs(0);
    vi vals;
    FOR(u, 1, n) if (!sz(adj[u])) {
        vals.pb(lev[u]);
    }
    sort(all(vals)), uni(vals);
    if (sz(vals) ^ 1) {
        while (q--) {
            int u; char c; cin >> u >> c; u--;
            cout << "Fou\n";
        }
        return;
    }
    vector<node_t> f(n);
    function<void(int)> upd_dfs = [&] (int u) {
        if (!sz(adj[u])) {
            f[u].z = 0;
        }
        for (int v : adj[u]) {
            upd_dfs(v);
            if (f[u].z == -1) {
                f[u] = add(f[v], c[v]);
            }
            else {
                f[u] = join(f[u], add(f[v], c[v]));
            }
        }
    };
    upd_dfs(0);
    while (q--) {
        int u; char x; cin >> u >> x; u--;
        char px = c[u];
        if (x != px) {
            int nu = nxt[u];
            vi change(26);
            vi vv;
            if (x != '?') {
                vv.pb(x - 'a');
            }
            if (px != '?') {
                vv.pb(px - 'a');
            }
            if (u ^ nu) {
                f[nu] = rem(f[nu], c[u]);
                c[u] = x;
                f[nu] = add(f[nu], c[u]);
                u = nu;
                if (px != '?') {
                    change[px - 'a'] = -1;
                }
                if (x != '?') {
                    change[x - 'a'] = 1;
                }
            }
            else {
                c[u] = x;
                if (u) {
                    int nu = nxt[par[u]];
                    node_t tmp = f[nu];
                    f[nu] = node_t();
                    for (int v : adj[nu]) {
                        if (f[nu].z == -1) {
                            f[nu] = add(f[v], c[v]);
                        }
                        else {
                            f[nu] = join(f[nu], add(f[v], c[v]));
                        }
                    }
                    for (int w : vv) {
                        change[w] = f[nu].vals[w] - tmp.vals[w];
                    }
                    u = nu;
                }
            }
            while (u) {
                nu = nxt[par[u]];
                if (sz(adj[nu]) == 1) {
                    f[nu] = add(f[u], c[u]);
                }
                else {
                    int v = adj[nu][0] + adj[nu][1] - u;
                    if (f[u].z == -1 || f[v].z == -1) {
                        f[nu].z = -1;
                    }
                    else {
                        for (int w : vv) {
                            f[u].vals[w] -= change[w];
                            int tmp = f[u].total;
                            if (f[v].vals[w] < f[u].vals[w]) {
                                f[nu].total -= f[u].vals[w] - f[v].vals[w];
                            }
                            f[u].vals[w] += change[w];
                            if (f[v].vals[w] < f[u].vals[w]) {
                                f[nu].total += f[u].vals[w] - f[v].vals[w];
                            }
                            change[w] = f[nu].total - tmp;
                        }
                        if (f[v].z < f[nu].total) {
                            f[nu].z = -1;
                        }
                        else {
                            f[nu].z = f[v].z - f[nu].total;
                        }
                    }
                }
                u = nu;
            }
        }
        if (f[0].z == -1) {
            cout << "Fou\n";
        }
        else {
            long long res = 0;
            FOR(i, 0, 26) {
                res += (i + 1) * (f[0].vals[i] + f[0].z);
            }
            cout << "Shi " << res << "\n";
        }
    }
}

int main(int argc, char* argv[]) {
    ios_base::sync_with_stdio(0), cin.tie(0);
    if (argc > 1) {
        assert(freopen(argv[1], "r", stdin));
    }
    if (argc > 2) {
        assert(freopen(argv[2], "wb", stdout));
    }
    solve();
    cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); --i)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int FFTMOD = 119 << 23 | 1;
const int INF = (int) 1e9 + 23111992;
const ll LINF = (ll) 1e18 + 23111992;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
inline ull isqrt(ull k) {ull r = sqrt(k) + 1; while (r * r > k) r--; return r;}
inline ll icbrt(ll k) {ll r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}
mt19937 mt(chrono::high_resolution_clock::now().time_since_epoch().count());
inline int mrand() {return abs((int) mt());}
#define db(x) cerr << "[" << #x << ": " << (x) << "] ";
#define endln cerr << "\n";

struct node_t {
    vi vals;
    vi difa;
    vi difb;
    int totala;
    int totalb;
    int z, w;
    node_t() {
        vals.resize(26);
        difa.resize(26);
        difb.resize(26);
        totala = totalb = 0;
        z = 0, w = 1;
    }
};

node_t join(node_t a, node_t b) {
    node_t c;
    FOR(i, 0, 26) {
        c.vals[i] = max(a.vals[i], b.vals[i]);
        if (a.vals[i] < b.vals[i]) {
            c.totala += b.vals[i] - a.vals[i];
            c.difa[i] = b.vals[i] - a.vals[i];
        }
        else {
            c.totalb += a.vals[i] - b.vals[i];
            c.difb[i] = a.vals[i] - b.vals[i];
        }
    }
    c.w = a.w & b.w;
    if (a.z < c.totala || b.z < c.totalb) {
        c.w = 0;
    }
    assert(a.z - c.totala == b.z - c.totalb);
    c.z = a.z - c.totala;
    return c;
}

void upd(node_t& c, node_t& a, node_t& b, int i) {
    c.vals[i] = max(a.vals[i], b.vals[i]);
    c.totala -= c.difa[i];
    c.totalb -= c.difb[i];
    if (a.vals[i] < b.vals[i]) {
        c.totala += b.vals[i] - a.vals[i];
        c.difa[i] = b.vals[i] - a.vals[i];
    }
    else {
        c.totalb += a.vals[i] - b.vals[i];
        c.difb[i] = a.vals[i] - b.vals[i];
    }
}
void upd(node_t& c, node_t& a, node_t& b) {
    c.w = a.w & b.w;
    if (a.z < c.totala || b.z < c.totalb) {
        c.w = 0;
    }
    assert(a.z - c.totala == b.z - c.totalb);
    c.z = a.z - c.totala;
}

node_t add(node_t a, char c) {
    if (c == '?') {
        a.z++;
    }
    else {
        a.vals[c - 'a']++;
    }
    return a;
}

node_t rem(node_t a, char c) {
    if (c == '?') {
        a.z--;
    }
    else {
        a.vals[c - 'a']--;
    }
    return a;
}

void upd_add(node_t& a, char c) {
    if (c == '?') {
        a.z++;
    }
    else {
        a.vals[c - 'a']++;
    }
}

void upd_rem(node_t& a, char c) {
    if (c == '?') {
        a.z--;
    }
    else {
        a.vals[c - 'a']--;
    }
}

void chemthan() {
    int n, q; cin >> n >> q;
    vector<vi> adj(n);
    vi par(n);
    vector<char> c(n);
    FOR(i, 1, n) {
        cin >> par[i] >> c[i]; par[i]--;
        adj[par[i]].pb(i);
    }
    vi dj(n);
    FOR(u, 0, n) dj[u] = u;
    function<int(int)> find = [&] (int u) {
        return dj[u] == u ? dj[u] : dj[u] = find(dj[u]);
    };
    FOR(u, 1, n) {
        if (sz(adj[u]) == 1) {
            int v = adj[u][0];
            if (sz(adj[v]) == 1) {
                dj[find(v)] = find(u);
            }
        }
    }
    vi lev(n);
    function<void(int)> dfs = [&] (int u) {
        for (int v : adj[u]) {
            lev[v] = lev[u] + 1;
            dfs(v);
        }
    };
    dfs(0);
    vi vals;
    FOR(u, 1, n) if (!sz(adj[u])) {
        vals.pb(lev[u]);
    }
    sort(all(vals)), uni(vals);
    if (sz(vals) ^ 1) {
        while (q--) {
            int u; char c; cin >> u >> c; u--;
            cout << "Fou\n";
        }
        return;
    }
    vector<node_t> f(n);
    function<void(int)> upd_dfs = [&] (int u) {
        int flag = 0;
        for (int v : adj[u]) {
            upd_dfs(v);
            if (!flag) {
                flag = 1;
                f[u] = f[v];
            }
            else {
                f[u] = join(f[u], f[v]);
            }
        }
        if (u) {
            f[u] = add(f[u], c[u]);
        }
    };
    upd_dfs(0);
    vector<vi> adj_t(n);
    vi from(n);
    FOR(u, 0, n) {
        for (int v : adj[u]) {
            int uu = find(u);
            int vv = find(v);
            if (uu ^ vv) {
                adj_t[uu].pb(vv);
                from[vv] = uu;
            }
        }
    }
    FOR(u, 0, n) {
        sort(all(adj_t[u])), uni(adj_t[u]);
    }
    while (q--) {
        int u; char x; cin >> u >> x; u--;
        char y = c[u];
        c[u] = x;
        if (x != y) {
            u = find(u);
            upd_add(f[u], x);
            upd_rem(f[u], y);
            while (u) {
                int nu = from[u];
                if (sz(adj_t[nu]) == 1) {
                    upd_add(f[nu], x);
                    upd_rem(f[nu], y);
                    f[nu].w = f[u].w;
                }
                else {
                    int v = adj_t[nu][0];
                    int w = adj_t[nu][1];
                    for (int ix : {x, y}) if ('a' <= ix && ix <= 'z') {
                        upd(f[nu], f[v], f[w], ix - 'a');
                    }
                    upd(f[nu], f[v], f[w]);
                    if (nu) {
                        upd_add(f[nu], c[nu]);
                    }
                }
                u = nu;
            }
        }
        if (!f[0].w) {
            cout << "Fou\n";
        }
        else {
            long long res = 0;
            FOR(i, 0, 26) {
                res += (i + 1) * (f[0].vals[i] + f[0].z);
            }
            cout << "Shi " << res << "\n";
        }
    }
}

int main(int argc, char* argv[]) {
    //ios_base::sync_with_stdio(0), cin.tie(0);
    if (argc > 1) {
        assert(freopen(argv[1], "r", stdin));
    }
    if (argc > 2) {
        assert(freopen(argv[2], "wb", stdout));
    }
    chemthan();
    cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); --i)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int FFTMOD = 119 << 23 | 1;
const int INF = (int) 1e9 + 23111992;
const ll LINF = (ll) 1e18 + 23111992;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
inline ull isqrt(ull k) {ull r = sqrt(k) + 1; while (r * r > k) r--; return r;}
inline ll icbrt(ll k) {ll r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}
mt19937 mt(chrono::high_resolution_clock::now().time_since_epoch().count());
inline int mrand() {return abs((int) mt());}
#define db(x) cerr << "[" << #x << ": " << (x) << "] ";
#define endln cerr << "\n";

struct node_t {
    vi vals;
    int z, total;
    node_t() {
        vals.resize(26);
        z = -1;
    }
};

node_t join(node_t a, node_t b) {
    if (a.z == -1 || b.z == -1) return node_t();
    node_t c;
    int total = 0;
    FOR(i, 0, 26) {
        c.vals[i] = max(a.vals[i], b.vals[i]);
        if (a.vals[i] < b.vals[i]) {
            total += b.vals[i] - a.vals[i];
        }
    }
    if (a.z < total) {
        return node_t();
    }
    c.z = a.z - total;
    c.total = total;
    return c;
}

node_t add(node_t a, char c) {
    if (a.z == -1) return a;
    if (c == '?') {
        a.z++;
    }
    else {
        a.vals[c - 'a']++;
    }
    return a;
}

node_t rem(node_t a, char c) {
    if (a.z == -1) return a;
    if (c == '?') {
        a.z--;
    }
    else {
        a.vals[c - 'a']--;
    }
    return a;
}

void upd_add(node_t& a, char c) {
    if (a.z == -1);
    if (c == '?') {
        a.z++;
    }
    else {
        a.vals[c - 'a']++;
    }
}

void upd_rem(node_t& a, char c) {
    if (a.z == -1) return;
    if (c == '?') {
        a.z--;
    }
    else {
        a.vals[c - 'a']--;
    }
}

void solve() {
    int n, q; cin >> n >> q;
    vector<vi> adj(n);
    vi par(n);
    vector<char> c(n);
    FOR(i, 1, n) {
        cin >> par[i] >> c[i]; par[i]--;
        adj[par[i]].pb(i);
    }
    vi lev(n);
    vi nxt(n);
    vi id(256);
    FOR(i, 'a', 'z' + 1) id[i] = i - 'a';
    id['?'] = 26;
    vector<vi> d(n, vi(27));
    FOR(u, 0, n) nxt[u] = u;
    function<void(int)> dfs = [&] (int u) {
        for (int v : adj[u]) {
            lev[v] = lev[u] + 1;
            if (sz(adj[u]) == 1) {
                nxt[v] = nxt[u];
            }
            dfs(v);
            if (nxt[v] != v) {
                d[nxt[v]][id[c[v]]]++;
            }
        }
    };
    dfs(0);
    vi vals;
    FOR(u, 1, n) if (!sz(adj[u])) {
        vals.pb(lev[u]);
    }
    sort(all(vals)), uni(vals);
    if (sz(vals) ^ 1) {
        while (q--) {
            int u; char c; cin >> u >> c; u--;
            cout << "Fou\n";
        }
        return;
    }
    vector<node_t> f(n);
    function<void(int)> upd_dfs = [&] (int u) {
        if (!sz(adj[u])) {
            f[u].z = 0;
        }
        for (int v : adj[u]) {
            upd_dfs(v);
            if (f[u].z == -1) {
                f[u] = add(f[v], c[v]);
            }
            else {
                f[u] = join(f[u], add(f[v], c[v]));
            }
        }
    };
    upd_dfs(0);
    auto calc = [&] (int u, char t) {
        return d[u][id[t]];
    };
    while (q--) {
        int u; char x; cin >> u >> x; u--;
        char px = c[u];
        if (x != px) {
            int nu = nxt[u];
            d[nu][id[px]]--;
            d[nu][id[x]]++;
            vi change(26), vv;
            if (x != '?') {
                vv.pb(id[x]);
            }
            if (px != '?') {
                vv.pb(id[px]);
            }
            if (u ^ nu) {
                f[nu] = rem(f[nu], c[u]);
                c[u] = x;
                f[nu] = add(f[nu], c[u]);
                u = nu;
                if (px != '?') {
                    change[px - 'a'] = -1;
                }
                if (x != '?') {
                    change[x - 'a'] = 1;
                }
            }
            else {
                c[u] = x;
                if (u) {
                    int nu = par[u];
                    f[nu] = node_t();
                    for (int v : adj[nu]) {
                        node_t tmp = f[v];
                        if (c[v] != '?') {
                            tmp.vals[id[c[v]]]++;
                        }
                        else {
                            tmp.z++;
                        }
                        if (f[nu].z == -1) {
                            f[nu] = tmp;
                        }
                        else {
                            f[nu] = join(f[nu], tmp);
                        }
                    }
                    u = nu, nu = nxt[u];
                    node_t tmp = f[nu];
                    f[nu] = f[u];
                    if (f[u].z == -1) {
                        f[nu].z = -1;
                    }
                    else {
                        FOR(i, 0, 26) {
                            f[nu].vals[i] += calc(nu, 'a' + i);
                        }
                        f[nu].z += calc(nu, '?');
                    }
                    for (int w : vv) {
                        change[w] = f[nu].vals[w] - tmp.vals[w];
                    }
                    u = nu;
                }
            }
            while (u) {
                nu = par[u];
                if (sz(adj[nu]) == 1) {
                    if (f[nu].z != -1) {
                        if (c[u] != '?') {
                            f[nu].vals[id[c[u]]]++;
                        }
                        else {
                            f[nu].z++;
                        }
                        nu = nxt[nu];
                        FOR(i, 0, 26) {
                            f[nu].vals[i] += calc(nu, 'a' + i);
                        }
                        f[nu].z += calc(nu, '?');
                    }
                }
                else {
                    int v = adj[nu][0] + adj[nu][1] - u;
                    if (f[u].z == -1 || f[v].z == -1) {
                        nu = nxt[nu];
                        f[nu].z = -1;
                    }
                    else {
                        for (int w : vv) {
                            int tmp = f[nu].vals[w];
                            f[u].vals[w] -= change[w];
                            f[u].vals[w] += c[u] == 'a' + w;
                            f[v].vals[w] += c[v] == 'a' + w;
                            if (f[v].vals[w] < f[u].vals[w]) {
                                f[nu].total -= f[u].vals[w] - f[v].vals[w];
                            }
                            else {
                                f[nu].total -= f[v].vals[w] - f[u].vals[w];
                            }
                            f[u].vals[w] += change[w];
                            if (f[v].vals[w] < f[u].vals[w]) {
                                f[nu].total += f[u].vals[w] - f[v].vals[w];
                            }
                            else {
                                f[nu].total += f[v].vals[w] - f[u].vals[w];
                            }
                            f[nu].vals[w] = max(f[u].vals[w], f[v].vals[w]);
                            f[u].vals[w] -= c[u] == 'a' + w;
                            f[v].vals[w] -= c[v] == 'a' + w;
                            change[w] = f[nu].vals[w] - tmp;
                        }
                        f[u].z += c[u] == '?';
                        f[v].z += c[v] == '?';
                        if (f[u].z + f[v].z < f[nu].total) {
                            nu = nxt[nu];
                            f[nu].z = -1;
                        }
                        else {
                            f[nu].z = (f[u].z + f[v].z - f[nu].total) / 2;
                            nu = nxt[nu];
                            FOR(i, 0, 26) {
                                f[nu].vals[i] += calc(nu, 'a' + i);
                            }
                            f[nu].z += calc(nu, '?');
                        }
                        f[u].z -= c[u] == '?';
                        f[v].z -= c[v] == '?';
                    }
                }
                u = nu;
            }
        }
        if (f[0].z == -1) {
            cout << "Fou\n";
        }
        else {
            long long res = 0;
            FOR(i, 0, 26) {
                res += (i + 1) * (f[0].vals[i] + f[0].z);
            }
            cout << "Shi " << res << "\n";
        }
    }
}

int main(int argc, char* argv[]) {
    ios_base::sync_with_stdio(0), cin.tie(0);
    if (argc > 1) {
        assert(freopen(argv[1], "r", stdin));
    }
    if (argc > 2) {
        assert(freopen(argv[2], "wb", stdout));
    }
    solve();
    cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
    return 0;
}