#include <bits/stdc++.h>
using namespace std;
const double PI = acos(-1.0);
const int N = 300005;
int lazy[N << 2];
complex<double> root[360];
complex<double> tree[N << 2], add[N << 2], mul[N << 2];
void push(int v, int s, int e) {
  if (lazy[v]) {
    tree[v] = mul[v] * tree[v] + add[v];
    if (s != e) {
      int v1 = v << 1;
      int v2 = v1 | 1;
      add[v1] = add[v1] * mul[v] + add[v];
      add[v2] = add[v2] * mul[v] + add[v];
      mul[v1] = mul[v1] * mul[v];
      mul[v2] = mul[v2] * mul[v];
      lazy[v1] = 1;
      lazy[v2] = 1;
    }
    mul[v] = 1.0;
    add[v] = 0.0;
    lazy[v] = 0;
  }
}
void build(int v, int l, int r) {
  lazy[v] = 0;
  add[v] = 0.0;
  mul[v] = 1.0;
  if (l == r) {
    tree[v] = l;
    return;
  }
  int m = (l + r) / 2;
  int v1 = v << 1;
  int v2 = v1 | 1;
  build(v1, l, m);
  build(v2, m + 1, r);
  tree[v] = tree[v1] + tree[v2];
}
void update(int v, int s, int e, int l, int r, complex<double> nad,
            complex<double> nmu) {
  if (l <= s && e <= r) {
    add[v] = add[v] * nmu + nad;
    mul[v] = mul[v] * nmu;
    lazy[v] = 1;
    push(v, s, e);
    return;
  }
  push(v, s, e);
  if (r < s || e < l || r < l) return;
  int m = (s + e) / 2;
  int v1 = v << 1;
  int v2 = v1 | 1;
  update(v1, s, m, l, r, nad, nmu);
  update(v2, m + 1, e, l, r, nad, nmu);
  tree[v] = tree[v1] + tree[v2];
}
complex<double> query(int v, int l, int r, int i) {
  push(v, l, r);
  if (l == r) return tree[v];
  int m = (l + r) / 2;
  int v1 = v << 1;
  int v2 = v1 | 1;
  if (i <= m) return query(v1, l, m, i);
  return query(v2, m + 1, r, i);
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout << setprecision(30);
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < 360; i++) {
    root[i] = complex<double>(cos(i * PI / 180), -sin(i * PI / 180));
  }
  build(1, 0, n);
  int x, y, z;
  while (m--) {
    cin >> x >> y >> z;
    if (x == 1) {
      complex<double> st = query(1, 0, n, y - 1);
      complex<double> en = query(1, 0, n, y);
      complex<double> nad = (en - st) / abs(en - st);
      nad *= z;
      update(1, 0, n, y, n, nad, 1.0);
    } else {
      complex<double> st = query(1, 0, n, y - 1);
      complex<double> en = query(1, 0, n, y);
      update(1, 0, n, y - 1, n, -st, 1.0);
      update(1, 0, n, y, n, 0.0, root[z]);
      update(1, 0, n, y - 1, n, st, 1.0);
    }
    complex<double> pt = query(1, 0, n, n);
    cout << pt.real() << " " << pt.imag() << '\n';
  }
  return 0;
}
