#include <bits/stdc++.h>
using namespace std;
const double PI = acos(-1.0);
const int maxn = 3e5 + 10;
struct node {
  double x, y, r;
  node() {}
  node(double x, double y, double r) : x(x), y(y), r(r) {}
  node operator+(const node &other) {
    node res;
    double len = sqrt(other.x * other.x + other.y * other.y);
    double ars = atan2(other.y, other.x);
    res.x = x + len * cos(ars + r);
    res.y = y + len * sin(ars + r);
    res.r = r + other.r;
    return res;
  }
} tree[maxn << 2];
void build(int id, int l, int r) {
  if (l == r) {
    tree[id] = node(1.0, 0.0, 0.0);
    return;
  }
  int mid = (l + r) >> 1;
  build(id << 1, l, mid);
  build(id << 1 | 1, mid + 1, r);
  tree[id] = tree[id << 1] + tree[id << 1 | 1];
}
void update(int id, int l, int r, int pos, double dx, double dr) {
  if (l == r) {
    double len = sqrt(tree[id].x * tree[id].x + tree[id].y * tree[id].y);
    double ars = atan2(tree[id].y, tree[id].x);
    len += dx;
    ars += dr;
    tree[id].x = len * cos(ars);
    tree[id].y = len * sin(ars);
    tree[id].r = ars;
    return;
  }
  int mid = (l + r) >> 1;
  if (pos <= mid)
    update(id << 1, l, mid, pos, dx, dr);
  else
    update(id << 1 | 1, mid + 1, r, pos, dx, dr);
  tree[id] = tree[id << 1] + tree[id << 1 | 1];
}
int n, m;
int x, y;
double z;
int main() {
  while (~scanf("%d %d", &n, &m)) {
    build(1, 1, n);
    for (int cas = 1; cas <= m; ++cas) {
      scanf("%d %d %lf", &x, &y, &z);
      if (x == 1) {
        update(1, 1, n, y, z, 0.0);
      } else {
        z = (360.0 - z) / 360.0 * 2.0 * PI;
        update(1, 1, n, y, 0.0, z);
      }
      printf("%.10f %.10f\n", tree[1].x, tree[1].y);
    }
  }
  return 0;
}
