#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1);
const double eps = 1e-10;
struct treenode {
  int addang;
  double len, ang;
};
treenode tree[1200000];
inline pair<double, double> turncoordinate(double len, double ang) {
  double x, y;
  x = len * cos(ang / 180 * pi);
  y = len * sin(ang / 180 * pi);
  return make_pair(x, y);
}
inline pair<double, double> turnvector(double x, double y) {
  double len, ang;
  len = sqrt(x * x + y * y);
  if (fabs(x) < eps)
    if (y < 0)
      ang = 270;
    else
      ang = 90;
  else {
    ang = 180 * atan(y / x) / pi;
    if (x < 0) ang = ang + 180;
  }
  return make_pair(len, ang);
}
inline treenode merge(treenode l, treenode r) {
  pair<double, double> C1 = turncoordinate(l.len, l.ang);
  pair<double, double> C2 = turncoordinate(r.len, r.ang);
  pair<double, double> C3 =
      turnvector(C1.first + C2.first, C1.second + C2.second);
  return (treenode){0, C3.first, C3.second};
}
inline void pushdown(int l, int r, int node) {
  if (tree[node].addang) {
    tree[node].ang = tree[node].ang + tree[node].addang;
    if (l != r) {
      tree[node << 1].addang = tree[node << 1].addang + tree[node].addang;
      tree[node << 1 | 1].addang =
          tree[node << 1 | 1].addang + tree[node].addang;
    }
    tree[node].addang = 0;
  }
  return;
}
inline void buildtree(int l, int r, int node) {
  if (l == r)
    tree[node].len = 1;
  else {
    int mid = (l + r) >> 1;
    buildtree(l, mid, node << 1);
    buildtree(mid + 1, r, node << 1 | 1);
    tree[node] = merge(tree[node << 1], tree[node << 1 | 1]);
  }
  return;
}
inline void inserttree(int l, int r, int x, int y, int node) {
  pushdown(l, r, node);
  if (l == r)
    tree[node].len = tree[node].len + y;
  else {
    int mid = (l + r) >> 1;
    if (x <= mid)
      inserttree(l, mid, x, y, node << 1);
    else
      inserttree(mid + 1, r, x, y, node << 1 | 1);
    pushdown(l, mid, node << 1);
    pushdown(mid + 1, r, node << 1 | 1);
    tree[node] = merge(tree[node << 1], tree[node << 1 | 1]);
  }
  return;
}
inline void inserttree(int l, int r, int x, int y, int z, int node) {
  pushdown(l, r, node);
  if ((l == x) && (r == y))
    tree[node].addang = tree[node].addang + z;
  else {
    int mid = (l + r) >> 1;
    if (y <= mid)
      inserttree(l, mid, x, y, z, node << 1);
    else if (x > mid)
      inserttree(mid + 1, r, x, y, z, node << 1 | 1);
    else {
      inserttree(l, mid, x, mid, z, node << 1);
      inserttree(mid + 1, r, mid + 1, y, z, node << 1 | 1);
    }
    pushdown(l, mid, node << 1);
    pushdown(mid + 1, r, node << 1 | 1);
    tree[node] = merge(tree[node << 1], tree[node << 1 | 1]);
  }
  return;
}
int i, m, n, t, x, y;
pair<double, double> T;
int main() {
  scanf("%d%d", &n, &m);
  buildtree(1, n, 1);
  for (i = 1; i <= m; i++) {
    scanf("%d", &t);
    if (t == 1) {
      scanf("%d%d", &x, &y);
      inserttree(1, n, x, y, 1);
    } else {
      scanf("%d%d", &x, &y);
      inserttree(1, n, x, n, 360 - y, 1);
    }
    pushdown(1, n, 1);
    T = turncoordinate(tree[1].len, tree[1].ang);
    printf("%.10lf %.10lf\n", T.first, T.second);
  }
  return 0;
}
