#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1.);
double Sin[361], Cos[361];
struct Tree {
  double p[3][3];
} T[300005 << 2];
Tree A, B, C, now, ans;
double x2, y2, x3, y3, len;
int flag[300005 << 2], n, i, ql, qr, m, opt, x, y;
Tree operator+(const Tree &a, const Tree &b) {
  Tree c;
  for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++) {
      c.p[i][j] = 0;
      for (int k = 0; k < 3; k++) c.p[i][j] += a.p[i][k] * b.p[k][j];
    }
  return c;
}
void Rotate(Tree &G, int beta) {
  G.p[0][2] = G.p[1][2] = G.p[2][0] = G.p[2][1] = 0;
  G.p[0][0] = G.p[1][1] = Cos[beta];
  G.p[1][0] = G.p[0][1] = Sin[beta];
  G.p[1][0] = -G.p[1][0];
  G.p[2][2] = 1;
}
void Shift(Tree &G, double xlen, double ylen) {
  G.p[0][1] = G.p[0][2] = G.p[1][0] = G.p[1][2] = 0;
  G.p[0][0] = G.p[1][1] = G.p[2][2] = 1;
  G.p[2][0] = xlen;
  G.p[2][1] = ylen;
}
Tree tmpA, tmpB, tmpC;
void Rotate(Tree &G, double x, double y, int beta) {
  Shift(tmpA, -x, -y);
  Rotate(tmpB, beta);
  Shift(tmpC, x, y);
  G = tmpA + tmpB + tmpC;
}
void Get(Tree &G, int x) {
  for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++) G.p[i][j] = 0;
  G.p[0][0] = x;
  G.p[0][2] = 1;
}
inline void down(int x) {
  if (!flag[x]) return;
  flag[x] = 0;
  flag[x << 1] = flag[x << 1 | 1] = 1;
  T[x << 1] = T[x << 1] + T[x];
  T[x << 1 | 1] = T[x << 1 | 1] + T[x];
  for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++) T[x].p[i][j] = (i == j);
}
void build(int x, int l, int r) {
  for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++) T[x].p[i][j] = (i == j);
  if (l == r) return;
  int mid = (l + r) >> 1;
  build(x << 1, l, mid);
  build(x << 1 | 1, mid + 1, r);
}
void Update(int x, int l, int r) {
  if (ql <= l && r <= qr) {
    T[x] = T[x] + now;
    flag[x] = 1;
    return;
  }
  int mid = (l + r) >> 1;
  down(x);
  if (ql <= mid) Update(x << 1, l, mid);
  if (qr > mid) Update(x << 1 | 1, mid + 1, r);
}
void Query(int pos, Tree &ret) {
  int x = 1, l = 1, r = n + 1;
  while (l < r) {
    int mid = (l + r) >> 1;
    down(x);
    if (pos <= mid)
      r = mid, x <<= 1;
    else
      l = mid + 1, x = x << 1 | 1;
  }
  Get(ret, pos - 1);
  ret = ret + T[x];
}
int main() {
  scanf("%d", &n);
  scanf("%d", &m);
  build(1, 1, n + 1);
  for (i = 0; i <= 360; i++) Cos[i] = cos(i / 180. * pi);
  for (i = 0; i <= 360; i++) Sin[i] = sin(i / 180. * pi);
  while (m--) {
    scanf("%d", &opt);
    scanf("%d", &x);
    scanf("%d", &y);
    if (opt == 1) {
      Query(x, A);
      Query(x + 1, B);
      x2 = A.p[0][0];
      y2 = A.p[0][1];
      x3 = B.p[0][0];
      y3 = B.p[0][1];
      len = (x3 - x2) * (x3 - x2) + (y3 - y2) * (y3 - y2);
      len = sqrt(len);
      len = y / len;
      Shift(now, (x3 - x2) * len, (y3 - y2) * len);
      ql = x + 1;
      qr = n + 1;
      Update(1, 1, n + 1);
    } else {
      y = (360 - y) % 360;
      Query(x, A);
      x2 = A.p[0][0];
      y2 = A.p[0][1];
      Rotate(now, x2, y2, y);
      ql = x + 1;
      qr = n + 1;
      Update(1, 1, n + 1);
    }
    for (i = n + 1; i <= n + 1; i++) {
      Query(i, ans);
      printf("%.10f %.10f\n", ans.p[0][0], ans.p[0][1]);
    }
  }
}
