#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1);
const int maxn = 3e5 + 10;
typedef struct node {
  int l, r;
  double degree;
  double x, y;
} Node;
int n, m;
Node tree[maxn * 4];
void Build(int l, int r, int num) {
  tree[num].l = l;
  tree[num].r = r;
  if (tree[num].l == tree[num].r) {
    tree[num].x = 1;
    tree[num].y = 0;
    tree[num].degree = 0;
  } else {
    int mid = (l + r) / 2;
    Build(l, mid, num << 1);
    Build(mid + 1, r, (num << 1) | 1);
    tree[num].x = tree[num << 1].x + tree[(num << 1) | 1].x;
    tree[num].y = tree[num << 1].y + tree[(num << 1) | 1].y;
    tree[num].degree = 0;
  }
  return;
}
void Update(int num, int k, int len, double degree) {
  int l = tree[num].l, r = tree[num].r;
  if (l == r && l == k) {
    double Len = sqrt(tree[num].x * tree[num].x + tree[num].y * tree[num].y);
    double degree1 = atan2(tree[num].y, tree[num].x);
    Len += len;
    degree1 += degree;
    tree[num].x = Len * cos(degree1);
    tree[num].y = Len * sin(degree1);
    tree[num].degree = degree1;
  } else {
    int mid = (l + r) / 2;
    if (k <= mid)
      Update(num << 1, k, len, degree);
    else
      Update((num << 1) | 1, k, len, degree);
    double Len = sqrt(tree[(num << 1) | 1].x * tree[(num << 1) | 1].x +
                      tree[(num << 1) | 1].y * tree[(num << 1) | 1].y);
    double degree1 = atan2(tree[(num << 1) | 1].y, tree[(num << 1) | 1].x);
    tree[num].x = tree[num << 1].x + Len * cos(degree1 + tree[num << 1].degree);
    tree[num].y = tree[num << 1].y + Len * sin(degree1 + tree[num << 1].degree);
    tree[num].degree = tree[num << 1].degree + tree[(num << 1) | 1].degree;
  }
  return;
}
int main() {
  scanf("%d%d", &n, &m);
  memset(tree, 0, sizeof(tree));
  Build(1, n, 1);
  while (m--) {
    int x, y, z;
    scanf("%d%d%d", &x, &y, &z);
    if (x == 1) {
      Update(1, y, z, 0);
    } else {
      Update(1, y, 0, -1.0 * z * pi / 180);
    }
    printf("%.10lf %.10lf\n", tree[1].x, tree[1].y);
  }
}
