#include <iostream>
#include <vector>
#include <cassert>
#include <cstdlib>

using namespace std;

long int randNumber ( long int min, long int max ){
  if (max==min) return min;
  long int toReturn = lrand48()%(max-min+1) + min;
  return toReturn;
}

vector<long int> differentRandNumbers ( uint total, long int min, long int max ){
  vector<long int> toReturn;
  if (total==0) return toReturn;
  
  assert(max>min);

  vector<long int> available(max-min+1);
  for (uint i=0;i<available.size();i++) available[i]=min+i;   

  uint left = total;

  while (toReturn.size()<total){
    long int n = randNumber(1,max-min+1);
    long int nAvailableFound=0;

    for (uint i=0;i<available.size();i++){
      if (available[i]!=-1) nAvailableFound++;
      if (nAvailableFound==n){
	toReturn.push_back(available[i]);      
	available[i]=-1;
	left--;
	break;
      }
    }
  }

  return toReturn;
}


int main ( int argc, char **argv ){

  if (argc!=5){
    cout << "Syntax is:" << endl << argv[0] << " nRegions minKmsCountry maxKmsCountry avgPointsPer10Km" << endl;
    exit(1);
  }
  
  int nRegions = atoi(argv[1]);
  int minKm = atoi(argv[2]);
  int maxKm = atoi(argv[3]);
  double avgPointsPerKm = ((double)(atoi(argv[4])))/10;
  
  if (maxKm<minKm) {
    cout << "minKmsCountry should be greater than maxKmsCountry" << endl;
    exit(1);
  }
  
  double FLEX_POINTS_REGION=0.2;
  double FLEX_BUDGET_REGION=0.3;
  double EXTRA_POINTS_STATIONS=0.5;
  double FLEX_PRICE_STATION=0.45;
  double PROB_NO_INCLUSION_DISTANCE_STATION=0.9;

  // Update random seed
  srand48((unsigned)time(0)); 
  
  // Generate kms of each region
  int longestRegion=0;
  vector<int> kmsRegion;
  kmsRegion.push_back(0); // indexing from 1 on
  for (int i=1;i<=nRegions;i++) {
    int kms=randNumber(minKm,maxKm);
    kmsRegion.push_back(kms);
    if (longestRegion<kms) longestRegion=kms;
  }
  
  // Generate points of each region
  vector<int> pointsRegion;
  pointsRegion.push_back(0);
  for (int i=1;i<=nRegions;i++){
    int kms = kmsRegion[i];
    int minPoints = avgPointsPerKm*kms*(1-FLEX_POINTS_REGION);
    int maxPoints = avgPointsPerKm*kms*(1+FLEX_POINTS_REGION);
    pointsRegion.push_back(randNumber(minPoints,maxPoints));    
  }
  
  // Generate budget of each region
  vector<int> budgetRegion;
  budgetRegion.push_back(0);
  for (int i=1;i<=nRegions;i++){
    int orig = pointsRegion[i]*1000;
    int minBudget = orig*(1-FLEX_BUDGET_REGION);
    int maxBudget = orig*(1+FLEX_BUDGET_REGION);
    budgetRegion.push_back(randNumber(minBudget,maxBudget));
  }
  
  cout << nRegions << endl;

  for (int i=1;i<=nRegions;i++)
    cout << kmsRegion[i] << " " << pointsRegion[i] << " " << budgetRegion[i] << endl;
  
  int totalPointsRegions=0;
  for (int i=1;i<=nRegions;i++) totalPointsRegions+=pointsRegion[i];


  int totalBudgetRegions=0;
  for (int i=1;i<=nRegions;i++) totalBudgetRegions+=budgetRegion[i];
  
  // Generate stations
  int totalPointsStations=0;
  int totalPriceStations=0;
  vector<int> pointsStation;  pointsStation.push_back(0);
  vector<int> priceStation;  priceStation.push_back(0);
  int nStations=0;
  while (totalPointsStations<(1+EXTRA_POINTS_STATIONS)*totalPointsRegions ||
	 nStations<3*nRegions){
    nStations++;
    int points = randNumber(1,10);
    pointsStation.push_back(points);
    int minPrice = 1000*points*(1-FLEX_PRICE_STATION);
    int maxPrice = 1000*points*(1+FLEX_PRICE_STATION);
    int price = randNumber(minPrice,maxPrice);
    priceStation.push_back(price);
    totalPointsStations+=points;
    totalPriceStations+=price;
  }
  
  cout << nStations << endl;
  for (int i=1;i<=nStations;i++)
    cout << pointsStation[i] << " " << priceStation[i] << endl;
  

  // Some stations at bigger distance
  for (int i=1;i<=nStations;i++){
    for (int j=i+1;j<=nStations;j++)
      if (pointsStation[i]>7 &&
	  pointsStation[j]>7 &&
	  double(randNumber(1,10))/10>PROB_NO_INCLUSION_DISTANCE_STATION){
	cout << i << " " << j << " " << randNumber(longestRegion,longestRegion*3) << endl;
      }
  }      

  cout << 0 << endl;

}

