#include <bits/stdc++.h>
using namespace std;
const double PI = 2 * acos(0.0);
struct mat {
  double m[3][3];
  mat() {
    for (int i = 0; i < 3; i++)
      for (int j = 0; j < 3; j++) m[i][j] = 0;
  }
  mat operator*(const mat& o) const {
    mat r = mat();
    for (int i = 0; i < 3; i++)
      for (int j = 0; j < 3; j++)
        for (int k = 0; k < 3; k++) r.m[i][j] += m[i][k] * o.m[k][j];
    return r;
  }
};
mat rotation(double angle) {
  mat r = mat();
  r.m[0][0] = cos(angle);
  r.m[0][1] = sin(angle);
  r.m[1][0] = -sin(angle);
  r.m[1][1] = cos(angle);
  r.m[2][2] = 1;
  return r;
}
mat translation(double dx, double dy) {
  mat r = mat();
  r.m[0][0] = 1;
  r.m[1][1] = 1;
  r.m[2][2] = 1;
  r.m[0][2] = dx;
  r.m[1][2] = dy;
  return r;
}
void make_I(mat& m) {
  for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++) m.m[i][j] = (i == j);
}
const int MAXN = 300100;
mat tree[4 * MAXN];
void update(int node, int b, int e, int i, int j, mat t) {
  if (i <= b && e <= j) {
    tree[node] = t * tree[node];
  } else {
    tree[2 * node + 1] = tree[node] * tree[2 * node + 1];
    tree[2 * node + 2] = tree[node] * tree[2 * node + 2];
    make_I(tree[node]);
    int m = (b + e) / 2;
    if (i <= m) update(2 * node + 1, b, m, i, j, t);
    if (m < j) update(2 * node + 2, m + 1, e, i, j, t);
  }
}
mat query(int node, int b, int e, int i) {
  if (b == e) {
    mat point = mat();
    point.m[0][0] = i;
    point.m[1][0] = 0;
    point.m[2][0] = 1;
    return tree[node] * point;
  }
  int m = (b + e) / 2;
  mat t = tree[node];
  if (i <= m) t = t * query(2 * node + 1, b, m, i);
  if (i > m) t = t * query(2 * node + 2, m + 1, e, i);
  return t;
}
int n, q, ind, qarg, op;
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout << fixed << setprecision(10);
  for (int i = 0; i < 4 * MAXN; i++) make_I(tree[i]);
  cin >> n >> q;
  while (q--) {
    cin >> op >> ind >> qarg;
    ind--;
    mat pos1 = query(0, 0, n, ind);
    double px = pos1.m[0][0];
    double py = pos1.m[1][0];
    mat pos2 = query(0, 0, n, ind + 1);
    double qx = pos2.m[0][0];
    double qy = pos2.m[1][0];
    if (op == 1) {
      double d = sqrt(((qx - px) * (qx - px)) + ((qy - py) * (qy - py)));
      assert(d > 0);
      double dx = 1.0 * qarg * (qx - px) / d;
      double dy = 1.0 * qarg * (qy - py) / d;
      mat transformation = translation(dx, dy);
      update(0, 0, n, ind + 1, n, transformation);
    } else {
      double dx = px;
      double dy = py;
      mat transformation = translation(dx, dy) * rotation(PI * qarg / 180) *
                           translation(-dx, -dy);
      update(0, 0, n, ind + 1, n, transformation);
    }
    mat sol = query(0, 0, n, n);
    double sx = sol.m[0][0];
    double sy = sol.m[1][0];
    cout << sx << " " << sy << '\n';
  };
}
