// Arup Guha
// 10/24/2023
// Solution (via Quick Sort) for COP 3502 Program 4: Projector Problems

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

#define EPS 1e-9
#define PI 3.14159265358979
#define MAX 1000000000

typedef struct group {
    double angle;
    int size;
    int id;
} group;

// Sorting Functions
group* makegroup(int x, int y, int numpeople, int myid, int offset);
int compare(group* ptrA, group* ptrB);
void swap(group** list, int idx1, int idx2);
int partition(group** list, int low, int high);
void quicksort(group** list, int n);
void qsortrec(group** list, int low, int high);

// Debugging functions
void printlist(group** list, int n);
void print(group* ptr);

// Problem Solving functions
double getmax(group** list, int n);
int mininlight(group** list, int n, double angle);
double todegrees(double radians);
double toradians(double degrees);

int main() {

    srand(time(0));

    // Read basic input.
    int n;
    double maxangle;
    scanf("%d%lf", &n, &maxangle);
    maxangle = toradians(maxangle);

    // Allocate pointers. Store two copies of each group.
    group** list = calloc(2*n, sizeof(group*));
    for (int i=0; i<n; i++) {
        int x, y, numpeople;
        scanf("%d%d%d", &x, &y, &numpeople);
        list[2*i] = makegroup(x, y, numpeople, 2*i, 0);
        list[2*i+1] = makegroup(x, y, numpeople, 2*i+1, 1);
    }

    // Sort it!
    quicksort(list, 2*n);

    // Ta da!
    printf("%d\n", mininlight(list, 2*n, maxangle));
    printf("%.4lf\n", todegrees(getmax(list, 2*n)));

    // Clean up.
    for (int i=0; i<2*n; i++)
        free(list[i]);
    free(list);

    return 0;
}

// Returns the equivalent of degrees degrees in radians.
double toradians(double degrees) {
    return degrees*PI/180.0;
}

// Returns the equivalent of radians radians in degrees.
double todegrees(double radians) {
    return radians*180/PI;
}

// Returns the maximum gap between angles in list.
double getmax(group** list, int n) {
    double res = 0;

    // Just look at each gap and update if one is larger.
    for (int i=0; i<n-1; i++)
        if (list[i+1]->angle - list[i]->angle > res)
            res = list[i+1]->angle - list[i]->angle;

    // Ta da!
    return res;
}

// Returns the minimum # of people in the light. Assumes that list is doubled and n is even.
int mininlight(group** list, int n, double angle) {

    // Set up variables.
    int j = 0, cursum = 0, res = MAX;

    // Just let i be every starting point.
    for (int i=0; i<n/2; i++) {

        // Move j as far as it can go.
        while (j < n && list[j]->angle - list[i]->angle < angle) {
            cursum += list[j]->size;
            j++;
        }

        // Not supposed to count this one, as we can slightly shift past it.
        cursum -= list[i]->size;

        // Update if better.
        if (cursum < res)
            res = cursum;
    }

    // Ta da!
    return res;
}

// Returns a group with this x, y coordinate and number of people with the unique id myid, and the number of
// revolutions of offset for the angle equal to offset.
group* makegroup(int x, int y, int numpeople, int myid, int offset) {

    // Allocate space.
    group* tmp = malloc(sizeof(group));

    // This is weird, but my hack so I could still use this function and assign different angles to the same point.
    tmp->angle = atan2(y, x) + offset*2*PI;

    // This is normal.
    tmp->size = numpeople;
    tmp->id = myid;
    return tmp;
}

// Returns a negative integer if the group pointed to by ptrA comes before ptrB, or a positive integer otherwise. 0 is only
// returned if both ids are the same (so really the same group).
int compare(group* ptrA, group* ptrB) {
    if (ptrA->angle - ptrB->angle < -EPS) return -1;
    if (ptrA->angle - ptrB->angle > EPS) return 1;
    return ptrA->id - ptrB->id;
}

// Wrapper function.
void quicksort(group** list, int n) {
    qsortrec(list, 0, n-1);
}

// Recursive quick sort of list[low..high].
void qsortrec(group** list, int low, int high) {

    // Done size 0 or 1.
    if (low >= high) return;

    // Partition...
    int mid = partition(list, low, high);

    // Recursively sort left of partition.
    qsortrec(list, low, mid-1);

    // Then right of partition.
    qsortrec(list, mid+1, high);
}

// Partitions list[low..high] returning the index of the partition element.
int partition(group** list, int low, int high) {

    // Swap partition index into place.
    int pIdx = low + rand()%(high-low+1);
    swap(list, low, pIdx);

    // Go through finding out of place elements and swapping...
    int i = low+1, j = high;
    while (i <= j) {

        // Find first out of place item on left.
        while (i<=high && compare(list[i], list[low]) < 0) i++;

        // Then right.
        while (j>=low && compare(list[j], list[low]) > 0) j--;

        // If actually out of place, swap.
        if (i < j) swap(list, i, j);
    }

    // Now put partition element in place.
    swap(list, low, j);

    // Index to return.
    return j;
}

// Swaps list[idx1] and list[idx2]/
void swap(group** list, int idx1, int idx2) {
    group* tmp = list[idx1];
    list[idx1] = list[idx2];
    list[idx2] = tmp;
}

// Prints a whole list for debugging.
void printlist(group** list, int n) {
    for (int i=0; i<n; i++)
        print(list[i]);
}

// Prints out info about the group pointed to by ptr.
void print(group* ptr) {
    printf("%d. %lf %d\n", ptr->id, ptr->angle, ptr->size);
}
