#include <bits/stdc++.h>
using namespace std;
void Solve1 ()
{
int cantitate , limita , lungime;
cin >> cantitate >> limita >> lungime;
vector <int> sir(cantitate);
for (auto& locatie : sir)
{ cin >> locatie; }
sort(sir.begin() , sir.end());
int64_t modalitati = 0;
for (int stanga = 0 , dreapta = 0 ; dreapta < cantitate ; dreapta++)
{
while (sir[dreapta] - sir[stanga] > limita)
{ stanga++; }
modalitati += dreapta - stanga;
}
cout << modalitati;
}
int arbore[150000];
void Update (int indice , const int termen , const int lungime)
{
for ( ; indice <= lungime ; indice += (indice & -indice))
{ arbore[indice] += termen; }
}
int Query (int stanga , int dreapta)
{
stanga--;
int rezultat = 0;
while (stanga != dreapta) {
if (stanga < dreapta) { rezultat += arbore[dreapta]; dreapta ^= (dreapta & -dreapta); }
else { rezultat -= arbore[stanga]; stanga ^= (stanga & -stanga); }
}
return rezultat;
}
void Solve2 ()
{
int cantitate , limita , lungime;
cin >> cantitate >> limita >> lungime;
vector < pair <int , int> > sir(cantitate);
for (auto& locatie : sir)
{
cin >> locatie.first >> locatie.second;
locatie = {locatie.first + locatie.second - 1 , locatie.first - locatie.second + lungime};
}
sort(sir.begin() , sir.end());
(lungime <<= 1)--;
int64_t modalitati = 0;
for (int stanga = 0 , dreapta = 0 ; dreapta < cantitate ; dreapta++)
{
while (sir[dreapta].first - sir[stanga].first > limita)
{ Update(sir[stanga].second , -1 , lungime); stanga++; }
modalitati += Query(max(1 , sir[dreapta].second - limita) , min(lungime , sir[dreapta].second + limita));
Update(sir[dreapta].second , 1 , lungime);
}
cout << modalitati;
}
int suma[225][225][225];
void __Update (const int __indice_1 , const int __indice_2 , const int __indice_3 , const int termen , const int lungime)
{
for (int indice_1 = __indice_1 ; indice_1 <= lungime ; indice_1 += (indice_1 & -indice_1)) {
for (int indice_2 = __indice_2 ; indice_2 <= lungime ; indice_2 += (indice_2 & -indice_2)) {
for (int indice_3 = __indice_3 ; indice_3 <= lungime ; indice_3 += (indice_3 & -indice_3))
{ suma[indice_1][indice_2][indice_3] += termen; }
}
}
}
int __Query (const int __stanga_1 , const int __dreapta_1 , const int __stanga_2 , const int __dreapta_2 , const int __stanga_3 , const int __dreapta_3)
{
int rezultat = 0;
for (int stanga_1 = __stanga_1 - 1 , dreapta_1 = __dreapta_1 ; stanga_1 != dreapta_1 ; )
{
const int factor_1 = (stanga_1 < dreapta_1 ? 1 : -1);
for (int stanga_2 = __stanga_2 - 1 , dreapta_2 = __dreapta_2 ; stanga_2 != dreapta_2 ; )
{
const int factor_2 = (stanga_2 < dreapta_2 ? 1 : -1);
for (int stanga_3 = __stanga_3 - 1 , dreapta_3 = __dreapta_3 ; stanga_3 != dreapta_3 ; )
{
const int factor_3 = (stanga_3 < dreapta_3 ? 1 : -1);
rezultat += factor_1 * factor_2 * factor_3 * suma[max(stanga_1 , dreapta_1)][max(stanga_2 , dreapta_2)][max(stanga_3 , dreapta_3)];
if (factor_3 < 0) { stanga_3 ^= (stanga_3 & -stanga_3); }
else { dreapta_3 ^= (dreapta_3 & -dreapta_3); }
}
if (factor_2 < 0) { stanga_2 ^= (stanga_2 & -stanga_2); }
else { dreapta_2 ^= (dreapta_2 & -dreapta_2); }
}
if (factor_1 < 0) { stanga_1 ^= (stanga_1 & -stanga_1); }
else { dreapta_1 ^= (dreapta_1 & -dreapta_1); }
}
return rezultat;
}
void Solve3 ()
{
int cantitate , limita , lungime;
cin >> cantitate >> limita >> lungime;
vector < array <int , 4> > sir(cantitate);
for (auto& locatie : sir)
{
cin >> locatie[0] >> locatie[1] >> locatie[2];
locatie = {locatie[0] + locatie[1] + locatie[2] , locatie[0] - locatie[1] + locatie[2] + lungime , locatie[0] + locatie[1] - locatie[2] + lungime , locatie[0] - locatie[1] - locatie[2] + 2 * lungime};
}
sort(sir.begin() , sir.end());
(lungime *= 3) -= 2;
int64_t modalitati = 0;
for (int stanga = 0 , dreapta = 0 ; dreapta < cantitate ; dreapta++)
{
while (sir[dreapta][0] - sir[stanga][0] > limita)
{ __Update(sir[stanga][1] , sir[stanga][2] , sir[stanga][3] , -1 , lungime); stanga++; }
modalitati += __Query(max(1 , sir[dreapta][1] - limita) , min(lungime , sir[dreapta][1] + limita) , max(1 , sir[dreapta][2] - limita) , min(lungime , sir[dreapta][2] + limita) , max(1 , sir[dreapta][3] - limita) , min(lungime , sir[dreapta][3] + limita));
__Update(sir[dreapta][1] , sir[dreapta][2] , sir[dreapta][3] , 1 , lungime);
}
cout << modalitati;
}
int main ()
{
ios :: sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
int cerinta;
cin >> cerinta;
if (cerinta == 1) { Solve1(); }
else if (cerinta == 2) { Solve2(); }
else { Solve3(); }
return 0;
}