#include <bits/stdc++.h>
using namespace std;
const long long INF = 1 << 28;
const long long LINF = 1ll << 61;
inline long long getnum() {
  register long long r = 0;
  register bool ng = 0;
  register char c;
  c = getchar();
  while (c != '-' && (c < '0' || c > '9')) c = getchar();
  if (c == '-') ng = 1, c = getchar();
  while (c != ' ' && c != '\n') r = r * 10 + c - '0', c = getchar();
  if (ng) r = -r;
  return r;
}
template <class T>
inline void putnum(T x) {
  if (x < 0) putchar('-'), x = -x;
  register short a[20] = {}, sz = 0;
  while (x > 0) a[sz++] = x % 10, x /= 10;
  if (sz == 0) putchar('0');
  for (int i = sz - 1; i >= 0; i--) putchar('0' + a[i]);
}
inline void putsp() { putchar(' '); }
inline void putendl() { putchar('\n'); }
inline char mygetchar() {
  register char c = getchar();
  while (c == ' ' || c == '\n') c = getchar();
  return c;
}
double eps = 1e-7;
struct cpx {
  double x, y;
  cpx(double X = 0, double Y = 0) {
    x = X;
    y = Y;
  }
  cpx operator+(cpx t) { return cpx(x + t.x, y + t.y); }
  cpx operator-(cpx t) { return cpx(x - t.x, y - t.y); }
  cpx operator*(cpx t) { return cpx(x * t.x - y * t.y, x * t.y + y * t.x); }
  cpx operator*(double t) { return cpx(x * t, y * t); }
  cpx operator/(double t) { return cpx(x / t, y / t); }
  void go() {
    if (x < eps && x > -eps) x = 0;
    if (y < eps && y > -eps) y = 0;
  }
  double len() { return sqrt(x * x + y * y); }
  cpx rad() { return (*this) / (*this).len(); }
};
double Sin[360], Cos[360];
struct SGT {
  struct node {
    int l, r;
    cpx v, last;
  } a[1200111];
  node update(node x, node y) {
    node ans;
    ans.l = x.l;
    ans.r = y.r;
    ans.v = x.v + y.v * x.last;
    ans.v.go();
    ans.last = x.last * y.last;
    return ans;
  }
  void build(int l, int r, int p = 1) {
    if (l == r) {
      a[p].l = l;
      a[p].r = r;
      a[p].v.x = a[p].last.x = 1;
      a[p].v.y = a[p].last.y = 0;
      return;
    }
    int m = l + r >> 1;
    build(l, m, p << 1);
    build(m + 1, r, p << 1 | 1);
    a[p] = update(a[p << 1], a[p << 1 | 1]);
  }
  void addrad(int x, int v, int p = 1) {
    int l = a[p].l, r = a[p].r;
    if (l == x && r == x) {
      a[p].v = a[p].v * cpx(Cos[v], -Sin[v]);
      a[p].last = a[p].last * cpx(Cos[v], -Sin[v]);
      return;
    }
    int m = l + r >> 1;
    if (x <= m)
      addrad(x, v, p << 1);
    else
      addrad(x, v, p << 1 | 1);
    a[p] = update(a[p << 1], a[p << 1 | 1]);
  }
  void addlen(int x, double v, int p = 1) {
    int l = a[p].l, r = a[p].r;
    if (l == x && r == x) {
      a[p].v = a[p].v.rad() * (a[p].v.len() + v);
      return;
    }
    int m = l + r >> 1;
    if (x <= m)
      addlen(x, v, p << 1);
    else
      addlen(x, v, p << 1 | 1);
    a[p] = update(a[p << 1], a[p << 1 | 1]);
  }
  void see(int p = 1) {
    cout << a[p].l << " " << a[p].r << " " << a[p].v.x << "," << a[p].v.y
         << endl;
    if (a[p].l == a[p].r) return;
    see(p << 1);
    see(p << 1 | 1);
  }
} sgt;
int n, m;
const double pi = acos(-1);
int main() {
  for (int i = 0; i < 360; i++)
    Sin[i] = sin(1.0 * i / 180 * pi), Cos[i] = cos(1.0 * i / 180 * pi);
  n = getnum(), m = getnum();
  sgt.build(1, n);
  while (m--) {
    int op, x, v;
    op = getnum(), x = getnum(), v = getnum();
    if (op == 1) {
      sgt.addlen(x, v);
    } else {
      sgt.addrad(x, v);
    }
    printf("%.10lf %.10lf\n", sgt.a[1].v.x, sgt.a[1].v.y);
  }
  return 0;
}
