#include <bits/stdc++.h>
const int maxn = 0x3f3f3f3f;
const double EI =
    2.71828182845904523536028747135266249775724709369995957496696762772407663035354594571382178525166427;
const double PI = 3.141592653589793238462643383279;
using namespace std;
struct node {
  int l, r;
  double x, y, a;
} tree[300010 * 4];
int n;
void pushup(int p) {
  double dis = sqrt(tree[2 * p + 1].x * tree[2 * p + 1].x +
                    tree[2 * p + 1].y * tree[2 * p + 1].y);
  double a = atan2(tree[2 * p + 1].y, tree[2 * p + 1].x);
  tree[p].x = tree[2 * p].x + dis * cos(tree[2 * p].a + a);
  tree[p].y = tree[2 * p].y + dis * sin(tree[2 * p].a + a);
  tree[p].a = tree[2 * p].a + tree[2 * p + 1].a;
  return;
}
void build(int l, int r, int p) {
  tree[p].l = l;
  tree[p].r = r;
  if (l + 1 == r) {
    tree[p].x = 1.0;
    tree[p].y = 0.0;
    tree[p].a = 0.0;
    return;
  }
  int k = ((l + r) >> 1);
  build(l, k, p << 1);
  build(k, r, (p << 1) + 1);
  pushup(p);
  return;
}
void update(int pos, double len, double aa, int p) {
  if (tree[p].l + 1 == tree[p].r) {
    double dis = sqrt(tree[p].x * tree[p].x + tree[p].y * tree[p].y);
    double a = atan2(tree[p].y, tree[p].x);
    dis += len, a += aa;
    tree[p].x = dis * cos(a);
    tree[p].y = dis * sin(a);
    tree[p].a = a;
    return;
  }
  if (pos <= tree[p << 1].r) {
    update(pos, len, aa, p << 1);
  } else {
    update(pos, len, aa, (p << 1) + 1);
  }
  pushup(p);
  return;
}
int main() {
  double val;
  int q, op, pos;
  while (~scanf("%d %d", &n, &q)) {
    build(0, n, 1);
    while (q--) {
      scanf("%d %d %lf", &op, &pos, &val);
      if (op == 1) {
        update(pos, val, 0, 1);
      } else {
        update(pos, 0, (1 - val / 360) * 2 * PI, 1);
      }
      printf("%.10f %.10f\n", tree[1].x, tree[1].y);
    }
  }
  return 0;
}
